diff --git a/.envrc b/.envrc index a6b1f81..f5141c2 100644 --- a/.envrc +++ b/.envrc @@ -1,4 +1,3 @@ -# shellcheck shell=bash if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" fi diff --git a/.woodpecker/check.yml b/.woodpecker/check.yml index 9e885aa..aff6e84 100644 --- a/.woodpecker/check.yml +++ b/.woodpecker/check.yml @@ -7,17 +7,17 @@ steps: commands: - nix flake check -- name: notify +- name: notifiy image: bash - environment: - ADDRESS: - from_secret: matrix_homeserver - ROOM: - from_secret: matrix_roomid - USER: - from_secret: matrix_username - PASS: - from_secret: matrix_password + 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: diff --git a/flake.lock b/flake.lock index b84e16d..4773d30 100644 --- a/flake.lock +++ b/flake.lock @@ -14,11 +14,11 @@ ] }, "locked": { - "lastModified": 1762618334, - "narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=", + "lastModified": 1703433843, + "narHash": "sha256-nmtA4KqFboWxxoOAA6Y1okHbZh+HsXaMPFkYHsoDRDw=", "owner": "ryantm", "repo": "agenix", - "rev": "fcdea223397448d35d9b31f798479227e80183f6", + "rev": "417caa847f9383e111d1397039c9d4337d024bf0", "type": "github" }, "original": { @@ -36,11 +36,11 @@ ] }, "locked": { - "lastModified": 1744478979, - "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", "owner": "lnl7", "repo": "nix-darwin", - "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", "type": "github" }, "original": { @@ -53,11 +53,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1761588595, - "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -73,11 +73,11 @@ ] }, "locked": { - "lastModified": 1763759067, - "narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=", + "lastModified": 1706830856, + "narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0", + "rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f", "type": "github" }, "original": { @@ -94,11 +94,11 @@ ] }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -108,42 +108,19 @@ "type": "github" } }, - "git-hooks": { - "inputs": { - "flake-compat": "flake-compat", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1763988335, - "narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "master", - "repo": "git-hooks.nix", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ - "git-hooks", + "pre-commit-hooks", "nixpkgs" ] }, "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "lastModified": 1703887061, + "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", "type": "github" }, "original": { @@ -159,11 +136,11 @@ ] }, "locked": { - "lastModified": 1764361670, - "narHash": "sha256-jgWzgpIaHbL3USIq0gihZeuy1lLf2YSfwvWEwnfAJUw=", + "lastModified": 1707175763, + "narHash": "sha256-0MKHC6tQ4KEuM5rui6DjKZ/VNiSANB4E+DJ/+wPS1PU=", "owner": "nix-community", "repo": "home-manager", - "rev": "780be8ef503a28939cf9dc7996b48ffb1a3e04c6", + "rev": "f99eace7c167b8a6a0871849493b1c613d0f1b80", "type": "github" }, "original": { @@ -175,11 +152,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1764242076, - "narHash": "sha256-sKoIWfnijJ0+9e4wRvIgm/HgE27bzwQxcEmo2J/gNpI=", + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2fad6eac6077f03fe109c4d4eb171cf96791faa4", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", "type": "github" }, "original": { @@ -190,38 +167,59 @@ } }, "nur": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1764449851, - "narHash": "sha256-VnodC1+3KML8MYLLnK84E6U2Fz4ioNacOeQd1pMCSTw=", + "lastModified": 1707234300, + "narHash": "sha256-D+LdA8g0Tq+KE9EmJMmn8EGRO5jZ2nLe/W0Fr5EIsdg=", "owner": "nix-community", "repo": "NUR", - "rev": "b1781c0aa8935d8d1f35d228bcc7127fcebcd363", + "rev": "59fceae769455455ef44c1dfb63bbae1ecddc41d", "type": "github" }, "original": { "owner": "nix-community", - "ref": "main", + "ref": "master", "repo": "NUR", "type": "github" } }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": [ + "futils" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1706424699, + "narHash": "sha256-Q3RBuOpZNH2eFA1e+IHgZLAOqDD9SKhJ/sszrL8bQD4=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "7c54e08a689b53c8a1e5d70169f2ec9e2a68ffaf", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "master", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "agenix": "agenix", "flake-parts": "flake-parts", "futils": "futils", - "git-hooks": "git-hooks", "home-manager": "home-manager", "nixpkgs": "nixpkgs", "nur": "nur", + "pre-commit-hooks": "pre-commit-hooks", "systems": "systems" } }, diff --git a/flake.nix b/flake.nix index 0bdd180..9c29183 100644 --- a/flake.nix +++ b/flake.nix @@ -54,20 +54,18 @@ type = "github"; owner = "nix-community"; repo = "NUR"; - ref = "main"; - inputs = { - flake-parts.follows = "flake-parts"; - nixpkgs.follows = "nixpkgs"; - }; + ref = "master"; }; - git-hooks = { + pre-commit-hooks = { type = "github"; owner = "cachix"; - repo = "git-hooks.nix"; + repo = "pre-commit-hooks.nix"; ref = "master"; inputs = { + flake-utils.follows = "futils"; nixpkgs.follows = "nixpkgs"; + nixpkgs-stable.follows = "nixpkgs"; }; }; diff --git a/flake/checks.nix b/flake/checks.nix index 73e64d5..98e49bd 100644 --- a/flake/checks.nix +++ b/flake/checks.nix @@ -1,7 +1,7 @@ { inputs, ... }: { imports = [ - inputs.git-hooks.flakeModule + inputs.pre-commit-hooks.flakeModule ]; perSystem = { ... }: { diff --git a/flake/default.nix b/flake/default.nix index 5e52025..65102e1 100644 --- a/flake/default.nix +++ b/flake/default.nix @@ -1,9 +1,9 @@ { flake-parts -, systems +, futils , ... } @ inputs: let - mySystems = import systems; + mySystems = futils.lib.defaultSystems; in flake-parts.lib.mkFlake { inherit inputs; } { systems = mySystems; diff --git a/flake/dev-shells.nix b/flake/dev-shells.nix index 87464a4..d5f5989 100644 --- a/flake/dev-shells.nix +++ b/flake/dev-shells.nix @@ -6,6 +6,7 @@ name = "NixOS-config"; nativeBuildInputs = with pkgs; [ + gitAndTools.pre-commit nixpkgs-fmt ]; diff --git a/flake/home-manager.nix b/flake/home-manager.nix index 88a74e8..34af375 100644 --- a/flake/home-manager.nix +++ b/flake/home-manager.nix @@ -3,11 +3,6 @@ let defaultModules = [ # Include generic settings "${self}/modules/home" - { - nixpkgs.overlays = (lib.attrValues self.overlays) ++ [ - inputs.nur.overlays.default - ]; - } { # Basic user information defaults home.username = lib.mkDefault "ambroisie"; @@ -22,15 +17,22 @@ let ]; mkHome = name: system: inputs.home-manager.lib.homeManagerConfiguration { - pkgs = inputs.nixpkgs.legacyPackages.${system}; + # 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}" ]; - # Use my extended lib in NixOS configuration - inherit (self) lib; - extraSpecialArgs = { # Inject inputs to use them in global registry inherit inputs; diff --git a/flake/nixos.nix b/flake/nixos.nix index 0fbd3a6..b48b551 100644 --- a/flake/nixos.nix +++ b/flake/nixos.nix @@ -3,11 +3,11 @@ let defaultModules = [ { # Let 'nixos-version --json' know about the Git revision - system.configurationRevision = self.rev or self.dirtyRev or "dirty"; + system.configurationRevision = self.rev or "dirty"; } { nixpkgs.overlays = (lib.attrValues self.overlays) ++ [ - inputs.nur.overlays.default + inputs.nur.overlay ]; } # Include generic settings @@ -15,10 +15,8 @@ let ]; buildHost = name: system: lib.nixosSystem { + inherit system; modules = defaultModules ++ [ - { - nixpkgs.hostPlatform = system; - } "${self}/hosts/nixos/${name}" ]; specialArgs = { diff --git a/flake/overlays.nix b/flake/overlays.nix index c10afc3..0c47989 100644 --- a/flake/overlays.nix +++ b/flake/overlays.nix @@ -1,4 +1,4 @@ -{ self, lib, ... }: +{ self, ... }: let default-overlays = import "${self}/overlays"; @@ -8,7 +8,7 @@ let # Expose my custom packages pkgs = _final: prev: { - ambroisie = lib.recurseIntoAttrs (import "${self}/pkgs" { pkgs = prev; }); + ambroisie = prev.recurseIntoAttrs (import "${self}/pkgs" { pkgs = prev; }); }; }; in diff --git a/hosts/homes/ambroisie@bazin/default.nix b/hosts/homes/ambroisie@bazin/default.nix index 365b70d..a969d8a 100644 --- a/hosts/homes/ambroisie@bazin/default.nix +++ b/hosts/homes/ambroisie@bazin/default.nix @@ -1,23 +1,9 @@ # Google Laptop configuration -{ lib, options, pkgs, ... }: +{ lib, pkgs, ... }: { services.gpg-agent.enable = lib.mkForce false; my.home = { - atuin = { - package = pkgs.stdenv.mkDerivation { - pname = "atuin"; - version = "18.4.0"; - - buildCommand = '' - mkdir -p $out/bin - ln -s /usr/bin/atuin $out/bin/atuin - ''; - - meta.mainProgram = "atuin"; - }; - }; - git = { package = pkgs.emptyDirectory; }; @@ -26,10 +12,8 @@ # I use scripts that use the passthrough sequence often on this host enablePassthrough = true; - terminalFeatures = { - # HTerm uses `xterm-256color` as its `$TERM`, so use that here - xterm-256color = { }; - }; + # HTerm uses `xterm-256color` as its `$TERM`, so use that here + trueColorTerminals = [ "xterm-256color" ]; }; ssh = { @@ -37,21 +21,5 @@ package = pkgs.emptyDirectory; }; }; - - zsh = { - notify = { - enable = true; - - exclude = options.my.home.zsh.notify.exclude.default ++ [ - "adb shell$" # Only interactive shell sessions - ]; - - ssh = { - enable = true; - # `notify-send` is proxied to the ChromeOS layer - useOsc777 = false; - }; - }; - }; }; } diff --git a/hosts/homes/ambroisie@mousqueton/default.nix b/hosts/homes/ambroisie@mousqueton/default.nix index 1383618..5c0a963 100644 --- a/hosts/homes/ambroisie@mousqueton/default.nix +++ b/hosts/homes/ambroisie@mousqueton/default.nix @@ -7,20 +7,6 @@ services.gpg-agent.enable = lib.mkForce false; my.home = { - atuin = { - package = pkgs.stdenv.mkDerivation { - pname = "atuin"; - version = "18.4.0"; - - buildCommand = '' - mkdir -p $out/bin - ln -s /usr/bin/atuin $out/bin/atuin - ''; - - meta.mainProgram = "atuin"; - }; - }; - git = { package = pkgs.emptyDirectory; }; @@ -29,13 +15,8 @@ # I use scripts that use the passthrough sequence often on this host enablePassthrough = true; - # Frequent reboots mean that session persistence can be handy - enableResurrect = true; - - terminalFeatures = { - # HTerm uses `xterm-256color` as its `$TERM`, so use that here - xterm-256color = { }; - }; + # HTerm uses `xterm-256color` as its `$TERM`, so use that here + trueColorTerminals = [ "xterm-256color" ]; }; }; } diff --git a/hosts/nixos/aramis/home.nix b/hosts/nixos/aramis/home.nix index e8c99e4..66a0892 100644 --- a/hosts/nixos/aramis/home.nix +++ b/hosts/nixos/aramis/home.nix @@ -2,7 +2,7 @@ { my.home = { # Use graphical pinentry - bitwarden.pinentry = pkgs.pinentry-gtk2; + bitwarden.pinentry = "gtk2"; # Ebook library calibre.enable = true; # Some amount of social life @@ -14,11 +14,13 @@ # Blue light filter gammastep.enable = true; # Use a small popup to enter passwords - gpg.pinentry = pkgs.pinentry-gtk2; + 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 + transgui # Transmission remote ]; # Minimal video player mpv.enable = true; @@ -26,8 +28,6 @@ nm-applet.enable = true; # Terminal terminal.program = "alacritty"; - # Transmission remote - trgui.enable = true; # Zathura document viewer zathura.enable = true; }; diff --git a/hosts/nixos/porthos/boot.nix b/hosts/nixos/porthos/boot.nix index 461e969..fbc5db7 100644 --- a/hosts/nixos/porthos/boot.nix +++ b/hosts/nixos/porthos/boot.nix @@ -3,14 +3,15 @@ { boot = { - # Use the systemd-boot EFI boot loader. - loader = { - systemd-boot.enable = true; - efi.canTouchEfiVariables = true; + # Use the GRUB 2 boot loader. + loader.grub = { + enable = true; + # Define on which hard drive you want to install Grub. + device = "/dev/disk/by-id/ata-HGST_HUS724020ALA640_PN2181P6J58M1P"; }; initrd = { - availableKernelModules = [ "ahci" "xhci_pci" "ehci_pci" "usbhid" "sd_mod" ]; + availableKernelModules = [ "uhci_hcd" "ahci" "usbhid" ]; kernelModules = [ "dm-snapshot" ]; }; diff --git a/hosts/nixos/porthos/default.nix b/hosts/nixos/porthos/default.nix index bd1bdb1..2dea899 100644 --- a/hosts/nixos/porthos/default.nix +++ b/hosts/nixos/porthos/default.nix @@ -16,5 +16,11 @@ # Set your time zone. time.timeZone = "Europe/Paris"; - system.stateVersion = "24.05"; # Did you read the comment? + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "20.09"; # Did you read the comment? } diff --git a/hosts/nixos/porthos/hardware.nix b/hosts/nixos/porthos/hardware.nix index 2172c5c..5a6e0d7 100644 --- a/hosts/nixos/porthos/hardware.nix +++ b/hosts/nixos/porthos/hardware.nix @@ -1,5 +1,5 @@ # Hardware configuration -{ modulesPath, ... }: +{ lib, modulesPath, ... }: { imports = [ @@ -11,18 +11,9 @@ fsType = "ext4"; }; - fileSystems."/boot" = { - device = "/dev/disk/by-label/boot"; - fsType = "vfat"; - }; - swapDevices = [ { device = "/dev/disk/by-label/swap"; } ]; - my.hardware = { - firmware = { - cpuFlavor = "intel"; - }; - }; + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; } diff --git a/hosts/nixos/porthos/home.nix b/hosts/nixos/porthos/home.nix index c2c858b..90aa0ec 100644 --- a/hosts/nixos/porthos/home.nix +++ b/hosts/nixos/porthos/home.nix @@ -1,18 +1,11 @@ { ... }: { my.home = { - nix = { - cache = { - # This server is the one serving the cache, don't try to query it - selfHosted = false; - }; - }; - - # Allow using extended features when SSH-ing from various clients - tmux.terminalFeatures = { + # Allow using 24bit color when SSH-ing from various clients + tmux.trueColorTerminals = [ # My usual terminal, e.g: on laptop - alacritty = { }; - }; + "alacritty" + ]; # Always start a tmux session when opening a shell session zsh.launchTmux = true; diff --git a/hosts/nixos/porthos/install.sh b/hosts/nixos/porthos/install.sh index e6ba0aa..8edc175 100644 --- a/hosts/nixos/porthos/install.sh +++ b/hosts/nixos/porthos/install.sh @@ -3,7 +3,7 @@ SWAP_SIZE=16GiB parted /dev/sda --script -- \ - mklabel gpt \ + mklabel msdos \ mkpart primary 512MiB -$SWAP_SIZE \ mkpart primary linux-swap -$SWAP_SIZE 100% \ mkpart ESP fat32 1MiB 512MiB \ @@ -11,24 +11,14 @@ parted /dev/sda --script -- \ parted /dev/sdb --script -- \ mklabel gpt \ - mkpart primary 0% 100% -parted /dev/sdc --script -- \ - mklabel gpt \ - mkpart primary 0% 100% -parted /dev/sdd --script -- \ - mklabel gpt \ - mkpart primary 0% 100% + mkpart primary 0MiB 100% mkfs.ext4 -L media1 /dev/sda1 mkfs.ext4 -L media2 /dev/sdb1 -mkfs.ext4 -L media3 /dev/sdc1 -mkfs.ext4 -L media4 /dev/sdd1 pvcreate /dev/sda1 pvcreate /dev/sdb1 -pvcreate /dev/sdc1 -pvcreate /dev/sdd1 -vgcreate lvm /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1 +vgcreate lvm /dev/sda1 /dev/sdb1 lvcreate -l 100%FREE -n media lvm mkfs.ext4 -L nixos /dev/mapper/lvm-media @@ -37,17 +27,17 @@ mkfs.fat -F 32 -n boot /dev/sda3 mount /dev/disk/by-label/nixos /mnt swapon /dev/sda2 -mkdir -p /mnt/boot -mount /dev/disk/by-label/boot /mnt/boot apt install sudo useradd -m -G sudo setupuser +# shellcheck disable=2117 +su setupuser cat << EOF # Run the following commands as setup user -curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install -. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh -nix profile install nixpkgs#nixos-install-tools +curl -L https://nixos.org/nix/install | sh +. $HOME/.nix-profile/etc/profile.d/nix.sh +nix-channel --add https://nixos.org/channels/nixos-20.09 nixpkgs sudo "$(which nixos-generate-config)" --root /mnt # Change uuids to labels @@ -64,6 +54,3 @@ git crypt unlock nixos-install --root /mnt --flake '.#' EOF - -# shellcheck disable=2117 -su setupuser diff --git a/hosts/nixos/porthos/networking.nix b/hosts/nixos/porthos/networking.nix index 717652b..1e2c9cd 100644 --- a/hosts/nixos/porthos/networking.nix +++ b/hosts/nixos/porthos/networking.nix @@ -6,17 +6,30 @@ hostName = "porthos"; # Define your hostname. domain = "belanyi.fr"; # Define your domain. - # Enables DHCP on each ethernet and wireless interface. In case of scripted networking - # (the default) this is the recommended approach. When using systemd-networkd it's - # still possible to use this option, but it's recommended to use it in conjunction - # with explicit per-interface declarations with `networking.interfaces..useDHCP`. - useDHCP = true; + + # The global useDHCP flag is deprecated, therefore explicitly set to false here. + # Per-interface useDHCP will be mandatory in the future, so this generated config + # replicates the default behaviour. + useDHCP = false; + interfaces = { - eno1.useDHCP = true; - eno2.useDHCP = true; + bond0.useDHCP = true; + bonding_masters.useDHCP = true; + dummy0.useDHCP = true; + erspan0.useDHCP = true; + eth0.useDHCP = true; + eth1.useDHCP = true; + gre0.useDHCP = true; + gretap0.useDHCP = true; + ifb0.useDHCP = true; + ifb1.useDHCP = true; + ip6tnl0.useDHCP = true; + sit0.useDHCP = true; + teql0.useDHCP = true; + tunl0.useDHCP = true; }; }; # Which interface is used to connect to the internet - my.hardware.networking.externalInterface = "eno1"; + my.hardware.networking.externalInterface = "eth0"; } diff --git a/hosts/nixos/porthos/secrets/acme/dns-key.age b/hosts/nixos/porthos/secrets/acme/dns-key.age index d7f159e..fce2a84 100644 --- a/hosts/nixos/porthos/secrets/acme/dns-key.age +++ b/hosts/nixos/porthos/secrets/acme/dns-key.age @@ -1,9 +1,8 @@ age-encryption.org/v1 --> ssh-ed25519 cKojmg Ec0xt1uJTva8MxUdoTVX5m3uWaIiRlodf345FEM7Uzs -aJIneWFJPB5HVeoUGp57agXih9YeZ6xMEbyQ+zJtWQY --> ssh-ed25519 jPowng B5XotRgv7s/FUegGhceBj7EoukewNUOIFl4TFRQf1EQ -PgGCBd/Pqwp7ayqi7okHBGF1SfFpwT4KlHJ/np6p2uQ ---- AeLgwGz6k3OABb53cXNaCU/sgI4FlU1s6p8PhAaFOlg -1CԹULfI1Hmb}m šg0`XG>\>8rz+Y`ʢ.JBU!z¸Z50*ٟI] I -ĵo۰g¿tncz[{ -j&NNo{ -eP=L 6.SP:e \ No newline at end of file +-> ssh-ed25519 cKojmg bQFr9oAnbo1rI/MpUV8wQz/Xj7iZY4ZU+Swf0nSIQFw +zama2XJ0gdvUlD2GHMhmZqHSxHe+dKSfXnHoWDcSw7Y +-> ssh-ed25519 jPowng gitUwSKTNKWLSxnwa185O7x/u0ul93g8wPESdZaKRk8 +uvBIfAUkZp5sg6rfeEGvL5ZDV8m2uSEotW02kjPN3Hw +--- SZxe5f/CUZBvPQa2Sz/UBY3L68rMkIGGRuZPk7YE+Vg +r&{~v?}= +}+ SQM[]k MAtmM/Ls|ޅmCiYC}x \ No newline at end of file diff --git a/hosts/nixos/porthos/secrets/forgejo/mail-password.age b/hosts/nixos/porthos/secrets/forgejo/mail-password.age deleted file mode 100644 index 67ef695..0000000 --- a/hosts/nixos/porthos/secrets/forgejo/mail-password.age +++ /dev/null @@ -1,10 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 cKojmg Lhgx43wR8PtAMf5v1eJxKlUBSAoOLdOOn/QaQrwF8zA -jfUCpgNzkHCNTWCqtErDaLMmg1Oy+s9zUra1JLCi+J4 --> ssh-ed25519 jPowng kSeQ/SmMrzd8ByVu3YHWeZyKmqFZvQSBnDunkB8e6wc -WRmnfrV5xcRXA9t0ZXx6YvbRl0sX4PTrw63VVKX4Ei4 ---- a+LLM1gP9g1AbUapbeeKaS4cEcRBmPo3MHU2DSWTAds -,F6⬘ ix̏e| - -Ϝ,{ v!z$P;TKW - qG \ No newline at end of file diff --git a/hosts/nixos/porthos/secrets/matrix/sliding-sync-secret.age b/hosts/nixos/porthos/secrets/matrix/sliding-sync-secret.age new file mode 100644 index 0000000..e938cfa --- /dev/null +++ b/hosts/nixos/porthos/secrets/matrix/sliding-sync-secret.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 cKojmg xRtF3XVc7yPicAV/E4U7mn0itvD0h1BWBTjwunuoe2E +OkB9sjGB3ulH4Feuyj3Ed0DBG4+mghW/Qpum9oXL/8c +-> ssh-ed25519 jPowng 1r8drqhz1yZdTq0Kvqya+ArU1C2fkN7Gg9LiWWfeUFg +cjbxntVwHvqLaJpiKs/Y8ojeb6e3/cLFcsoeuoobfFg +--- B1qA2PylJBrdZxZtCzlU2kRPvxLM+IrXTvR+ERxVtTY +"W9bg~/b4ՆI +} -NC7vWb?8=wB UpJClOșnO\ \ No newline at end of file diff --git a/hosts/nixos/porthos/secrets/mealie/mail.age b/hosts/nixos/porthos/secrets/mealie/mail.age deleted file mode 100644 index b7348ae..0000000 Binary files a/hosts/nixos/porthos/secrets/mealie/mail.age and /dev/null differ diff --git a/hosts/nixos/porthos/secrets/pdf-edit/login.age b/hosts/nixos/porthos/secrets/pdf-edit/login.age deleted file mode 100644 index 7f13f88..0000000 --- a/hosts/nixos/porthos/secrets/pdf-edit/login.age +++ /dev/null @@ -1,8 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 cKojmg VYlHgHSLpfKb5bn1XA3aCpfX7M23DgbraLxxOfo9PDk -Rj+mDvAsWX3WwpuhTrOubmo17j/aud5+P87df5bosBA --> ssh-ed25519 jPowng o9ZFaYrITZ6DjWw07Vk/+TkuU187/ytlEK4sw7G32G4 -zmxlpDvDDEgQFqBVARXeX1ABhvfJ4uAHfa6mIxXzjAY ---- k/d9FWW8/OSo8EllwOBV74pZyX918u54jEljGk3ATUc -4+2{hE7!ҭGA`ׁ_@ߗR_6JL4v,6%#^  BOF|7ܽL]jR -B۾as]xS pbo#J1Q=t}5>O{+. M"7ey \ No newline at end of file diff --git a/hosts/nixos/porthos/secrets/secrets.nix b/hosts/nixos/porthos/secrets/secrets.nix index f1842b4..43a9b35 100644 --- a/hosts/nixos/porthos/secrets/secrets.nix +++ b/hosts/nixos/porthos/secrets/secrets.nix @@ -21,24 +21,13 @@ in "drone/secret.age".publicKeys = all; "drone/ssh/private-key.age".publicKeys = all; - "forgejo/mail-password.age" = { - owner = "git"; - publicKeys = all; - }; - "gitea/mail-password.age" = { owner = "git"; publicKeys = all; }; - "lohr/secret.age" = { - owner = "lohr"; - publicKeys = all; - }; - "lohr/ssh-key.age" = { - owner = "lohr"; - publicKeys = all; - }; + "lohr/secret.age".publicKeys = all; + "lohr/ssh-key.age".publicKeys = all; "matrix/mail.age" = { owner = "matrix-synapse"; @@ -48,8 +37,7 @@ in owner = "matrix-synapse"; publicKeys = all; }; - - "mealie/mail.age" = { + "matrix/sliding-sync-secret.age" = { publicKeys = all; }; @@ -74,15 +62,10 @@ in "paperless/password.age".publicKeys = all; "paperless/secret-key.age".publicKeys = all; - "pdf-edit/login.age".publicKeys = all; - "podgrab/password.age".publicKeys = all; "pyload/credentials.age".publicKeys = all; - "servarr/autobrr/session-secret.age".publicKeys = all; - "servarr/cross-seed/configuration.json.age".publicKeys = all; - "sso/auth-key.age".publicKeys = all; "sso/ambroisie/password-hash.age".publicKeys = all; "sso/ambroisie/totp-secret.age".publicKeys = all; diff --git a/hosts/nixos/porthos/secrets/servarr/autobrr/session-secret.age b/hosts/nixos/porthos/secrets/servarr/autobrr/session-secret.age deleted file mode 100644 index e98b94a..0000000 --- a/hosts/nixos/porthos/secrets/servarr/autobrr/session-secret.age +++ /dev/null @@ -1,7 +0,0 @@ -age-encryption.org/v1 --> ssh-ed25519 cKojmg bu09lB+fjaPP31cUQZP6EqSPuseucgNK7k9vAS08iS0 -+NGL+b2QD/qGo6hqHvosAXzHZtDvfodmPdcgnrKlD1o --> ssh-ed25519 jPowng QDCdRBGWhtdvvMCiDH52cZHz1/W7aomhTatZ4+9IKwI -Ou3jjV/O55G1CPgGS33l3eWhhYWrVdwVNPSiE14d5rE ---- q0ssmpG50OX1WaNSInc2hbtH3DbTwQGDU74VGEoMh94 -mCƑ'hK./Xu(g$'M{fK !MZoR՝͟;yb \ No newline at end of file diff --git a/hosts/nixos/porthos/secrets/servarr/cross-seed/configuration.json.age b/hosts/nixos/porthos/secrets/servarr/cross-seed/configuration.json.age deleted file mode 100644 index 94fdf97..0000000 Binary files a/hosts/nixos/porthos/secrets/servarr/cross-seed/configuration.json.age and /dev/null differ diff --git a/hosts/nixos/porthos/services.nix b/hosts/nixos/porthos/services.nix index 96f15d3..2486752 100644 --- a/hosts/nixos/porthos/services.nix +++ b/hosts/nixos/porthos/services.nix @@ -10,11 +10,6 @@ in adblock = { enable = true; }; - # Audiobook and podcast library - audiobookshelf = { - enable = true; - port = 9599; - }; # Backblaze B2 backup backup = { enable = true; @@ -41,19 +36,19 @@ in flood = { enable = true; }; - # Forgejo forge - forgejo = { + # Gitea forge + gitea = { enable = true; mail = { enable = true; - host = "smtp.migadu.com"; - user = lib.my.mkMailAddress "forgejo" "belanyi.fr"; - passwordFile = secrets."forgejo/mail-password".path; + host = "smtp.migadu.com:465"; + user = lib.my.mkMailAddress "gitea" "belanyi.fr"; + passwordFile = secrets."gitea/mail-password".path; }; }; - # Home inventory - homebox = { - enable = true; + # Meta-indexers + indexers = { + prowlarr.enable = true; }; # Jellyfin media server jellyfin.enable = true; @@ -69,10 +64,9 @@ in mailConfigFile = secrets."matrix/mail".path; # Only necessary when doing the initial registration secretFile = secrets."matrix/secret".path; - }; - mealie = { - enable = true; - credentialsFile = secrets."mealie/mail".path; + slidingSync = { + secretFile = secrets."matrix/sliding-sync-secret".path; + }; }; miniflux = { enable = true; @@ -95,9 +89,6 @@ in nextcloud = { enable = true; passwordFile = secrets."nextcloud/password".path; - collabora = { - enable = true; - }; }; nix-cache = { enable = true; @@ -127,10 +118,19 @@ in passwordFile = secrets."paperless/password".path; secretKeyFile = secrets."paperless/secret-key".path; }; - # Sometimes, editing PDFs is useful - pdf-edit = { + # The whole *arr software suite + pirate = { enable = true; - loginFile = secrets."pdf-edit/login".path; + # ... But not Lidarr because I don't care for music that much + lidarr = { + enable = false; + }; + }; + # Podcast automatic downloader + podgrab = { + enable = true; + passwordFile = secrets."podgrab/password".path; + port = 9598; }; # Regular backups postgresql-backup.enable = true; @@ -142,29 +142,13 @@ in rss-bridge.enable = true; # Usenet client sabnzbd.enable = true; - # The whole *arr software suite - servarr = { - enableAll = true; - autobrr = { - sessionSecretFile = secrets."servarr/autobrr/session-secret".path; - }; - cross-seed = { - secretSettingsFile = secrets."servarr/cross-seed/configuration.json".path; - }; - # ... But not Lidarr because I don't care for music that much - lidarr = { - enable = false; - }; - # I only use Prowlarr nowadays - jackett = { - enable = false; - }; - nzbhydra = { - enable = false; - }; - }; - # Because I still need to play sysadmin + # 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; diff --git a/modules/home/atuin/default.nix b/modules/home/atuin/default.nix index 40d2b04..19a6fb9 100644 --- a/modules/home/atuin/default.nix +++ b/modules/home/atuin/default.nix @@ -1,26 +1,15 @@ -{ config, lib, pkgs, ... }: +{ config, lib, ... }: let cfg = config.my.home.atuin; in { options.my.home.atuin = with lib; { enable = my.mkDisableOption "atuin configuration"; - - package = mkPackageOption pkgs "atuin" { }; - - daemon = { - enable = my.mkDisableOption "atuin daemon"; - }; }; config = lib.mkIf cfg.enable { programs.atuin = { enable = true; - inherit (cfg) package; - - daemon = lib.mkIf cfg.daemon.enable { - enable = true; - }; flags = [ # I *despise* this hijacking of the up key, even though I use Ctrl-p @@ -28,8 +17,6 @@ in ]; settings = { - # Reasonable date format - dialect = "uk"; # The package is managed by Nix update_check = false; # I don't care for the fancy display @@ -38,8 +25,6 @@ in search_mode = "skim"; # Show long command lines at the bottom show_preview = true; - # I like being able to edit my commands - enter_accept = false; }; }; }; diff --git a/modules/home/bitwarden/default.nix b/modules/home/bitwarden/default.nix index 0c0dfab..c709f7b 100644 --- a/modules/home/bitwarden/default.nix +++ b/modules/home/bitwarden/default.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, ... }: let cfg = config.my.home.bitwarden; in @@ -6,7 +6,12 @@ in options.my.home.bitwarden = with lib; { enable = my.mkDisableOption "bitwarden configuration"; - pinentry = mkPackageOption pkgs "pinentry" { default = [ "pinentry-tty" ]; }; + pinentry = mkOption { + type = types.str; + default = "tty"; + example = "gtk2"; + description = "Which pinentry interface to use"; + }; }; config = lib.mkIf cfg.enable { diff --git a/modules/home/calibre/default.nix b/modules/home/calibre/default.nix index de7c126..6edf654 100644 --- a/modules/home/calibre/default.nix +++ b/modules/home/calibre/default.nix @@ -5,13 +5,11 @@ in { options.my.home.calibre = with lib; { enable = mkEnableOption "calibre configuration"; - - package = mkPackageOption pkgs "calibre" { }; }; config = lib.mkIf cfg.enable { home.packages = with pkgs; [ - cfg.package + calibre ]; }; } diff --git a/modules/home/default.nix b/modules/home/default.nix index ad3b979..c8183cf 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -8,7 +8,6 @@ ./bluetooth ./calibre ./comma - ./delta ./dircolors ./direnv ./discord @@ -38,7 +37,6 @@ ./ssh ./terminal ./tmux - ./trgui ./udiskie ./vim ./wget @@ -52,6 +50,9 @@ # First sane reproducible version home.stateVersion = "20.09"; + # Who am I? + home.username = "ambroisie"; + # Start services automatically systemd.user.startServices = "sd-switch"; } diff --git a/modules/home/delta/default.nix b/modules/home/delta/default.nix deleted file mode 100644 index e76edc6..0000000 --- a/modules/home/delta/default.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ config, pkgs, lib, ... }: -let - cfg = config.my.home.delta; -in -{ - options.my.home.delta = with lib; { - enable = my.mkDisableOption "delta configuration"; - - package = mkPackageOption pkgs "delta" { }; - - git = { - enable = my.mkDisableOption "git integration"; - }; - }; - - config = lib.mkIf cfg.enable { - programs.delta = { - enable = true; - - inherit (cfg) package; - - enableGitIntegration = cfg.git.enable; - - options = { - features = "diff-highlight decorations"; - - # Less jarring style for `diff-highlight` emulation - diff-highlight = { - minus-style = "red"; - minus-non-emph-style = "red"; - minus-emph-style = "bold red 52"; - - plus-style = "green"; - plus-non-emph-style = "green"; - plus-emph-style = "bold green 22"; - - whitespace-error-style = "reverse red"; - }; - - # Personal preference for easier reading - decorations = { - commit-style = "raw"; # Do not recolor meta information - keep-plus-minus-markers = true; - paging = "always"; - }; - }; - }; - }; -} diff --git a/modules/home/direnv/default.nix b/modules/home/direnv/default.nix index 67beb62..93a1f3b 100644 --- a/modules/home/direnv/default.nix +++ b/modules/home/direnv/default.nix @@ -7,9 +7,9 @@ in enable = my.mkDisableOption "direnv configuration"; defaultFlake = mkOption { - type = with types; nullOr str; - default = null; - example = "pkgs"; + type = types.str; + default = "pkgs"; + example = "nixpkgs"; description = '' Which flake from the registry should be used for use pkgs by default. @@ -39,7 +39,7 @@ in in lib.my.genAttrs' files linkLibFile; - home.sessionVariables = lib.mkIf (cfg.defaultFlake != null) { + home.sessionVariables = { DIRENV_DEFAULT_FLAKE = cfg.defaultFlake; }; }; diff --git a/modules/home/direnv/lib/android.sh b/modules/home/direnv/lib/android.sh index 9344aea..fa2f856 100644 --- a/modules/home/direnv/lib/android.sh +++ b/modules/home/direnv/lib/android.sh @@ -1,4 +1,4 @@ -# shellcheck shell=bash +#shellcheck shell=bash # shellcheck disable=2155 use_android() { @@ -32,16 +32,10 @@ use_android() { -b|--build-tools) build_tools_version="$2" shift 2 - if ! [ -e "$ANDROID_HOME/build-tools/$build_tools_version" ]; then - log_error "use_android: build-tools version '$build_tools_version' does not exist" - fi ;; -n|--ndk) ndk_version="$2" shift 2 - if ! [ -e "$ANDROID_HOME/ndk/$ndk_version" ]; then - log_error "use_android: NDK version '$ndk_version' does not exist" - fi ;; --) shift diff --git a/modules/home/direnv/lib/nix.sh b/modules/home/direnv/lib/nix.sh index 4b6c547..a65eb31 100644 --- a/modules/home/direnv/lib/nix.sh +++ b/modules/home/direnv/lib/nix.sh @@ -1,4 +1,4 @@ -# shellcheck shell=bash +#shellcheck shell=bash use_pkgs() { if ! has nix; then diff --git a/modules/home/direnv/lib/postgres.sh b/modules/home/direnv/lib/postgres.sh index 46e171d..c2e6a8f 100644 --- a/modules/home/direnv/lib/postgres.sh +++ b/modules/home/direnv/lib/postgres.sh @@ -1,4 +1,4 @@ -# shellcheck shell=bash +#shellcheck shell=bash layout_postgres() { if ! has postgres || ! has initdb; then diff --git a/modules/home/direnv/lib/python.sh b/modules/home/direnv/lib/python.sh index b1be8a9..15a273f 100644 --- a/modules/home/direnv/lib/python.sh +++ b/modules/home/direnv/lib/python.sh @@ -1,4 +1,4 @@ -# shellcheck shell=bash +#shellcheck shell=bash layout_poetry() { if ! has poetry; then @@ -9,12 +9,12 @@ layout_poetry() { if [[ ! -f pyproject.toml ]]; then # shellcheck disable=2016 - log_error 'layout_poetry: no pyproject.toml found. Use `poetry init` to create one first' + log_error 'layout_poetry: no pyproject.toml found. Use `poetry new` or `poetry init` to create one first' return 1 fi # create venv if it doesn't exist - poetry run -q -- true + poetry run true # shellcheck disable=2155 export VIRTUAL_ENV=$(poetry env info --path) @@ -23,35 +23,3 @@ layout_poetry() { watch_file pyproject.toml watch_file poetry.lock } - -layout_uv() { - if ! has uv; then - # shellcheck disable=2016 - log_error 'layout_uv: `uv` is not in PATH' - return 1 - fi - - if [[ ! -f pyproject.toml ]]; then - # shellcheck disable=2016 - log_error 'layout_uv: no pyproject.toml found. Use `uv init` to create one first' - return 1 - fi - - local default_venv="$PWD/.venv" - : "${VIRTUAL_ENV:=$default_venv}" - - # Use non-default venv path if required - if [ "$VIRTUAL_ENV" != "$default_venv" ]; then - export UV_PROJECT_ENVIRONMENT="$VIRTUAL_ENV" - fi - - # create venv if it doesn't exist - uv venv -q --allow-existing - - export VIRTUAL_ENV - export UV_ACTIVE=1 - PATH_add "$VIRTUAL_ENV/bin" - watch_file pyproject.toml - watch_file uv.lock - watch_file .python-version -} diff --git a/modules/home/discord/default.nix b/modules/home/discord/default.nix index f9892df..7348bb4 100644 --- a/modules/home/discord/default.nix +++ b/modules/home/discord/default.nix @@ -1,24 +1,23 @@ { config, lib, pkgs, ... }: let cfg = config.my.home.discord; + + jsonFormat = pkgs.formats.json { }; in { options.my.home.discord = with lib; { enable = mkEnableOption "discord configuration"; - - package = mkPackageOption pkgs "discord" { }; }; config = lib.mkIf cfg.enable { - programs.discord = { - enable = true; + home.packages = with pkgs; [ + discord + ]; - inherit (cfg) package; - - settings = { + xdg.configFile."discord/settings.json".source = + jsonFormat.generate "discord.json" { # Do not keep me from using the app just to force an update SKIP_HOST_UPDATE = true; }; - }; }; } diff --git a/modules/home/firefox/default.nix b/modules/home/firefox/default.nix index 6346dc9..02c74f2 100644 --- a/modules/home/firefox/default.nix +++ b/modules/home/firefox/default.nix @@ -61,21 +61,19 @@ in "ui.systemUsesDarkTheme" = true; # Dark mode }; - extensions = { - packages = 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 + 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/modules/home/firefox/tridactyl/default.nix b/modules/home/firefox/tridactyl/default.nix index 26ddfad..35b58c2 100644 --- a/modules/home/firefox/tridactyl/default.nix +++ b/modules/home/firefox/tridactyl/default.nix @@ -12,7 +12,9 @@ let in { config = lib.mkIf cfg.enable { - xdg.configFile."tridactyl/tridactylrc".source = pkgs.replaceVars ./tridactylrc { + xdg.configFile."tridactyl/tridactylrc".source = pkgs.substituteAll { + src = ./tridactylrc; + editorcmd = lib.concatStringsSep " " [ # Use my configured terminal term diff --git a/modules/home/firefox/tridactyl/tridactylrc b/modules/home/firefox/tridactyl/tridactylrc index 775719c..4dc53cf 100644 --- a/modules/home/firefox/tridactyl/tridactylrc +++ b/modules/home/firefox/tridactyl/tridactylrc @@ -4,7 +4,7 @@ " Use dark color scheme colorscheme dark -" Make tridactyl open Vim in my preferred terminal +" Make tridactyl open Vim in my prefered terminal set editorcmd @editorcmd@ " Remove editor file after use @@ -15,8 +15,8 @@ bind --mode=input editor_rm " Binds {{{ " Reddit et al. {{{ -" Toggle comments on Reddit, Hacker News, Lobste.rs, LWN -bind ;c hint -Jc [class*="expand"],[class*="togg"],[class="comment_folder"],[class="CommentTitle"] +" Toggle comments on Reddit, Hacker News, Lobste.rs +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 @@ -26,8 +26,8 @@ bindurl www.google.com f hint -Jc #search a bindurl www.google.com F hint -Jbc #search a " Only hint search results on DuckDuckGo -bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result"] -bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result"] +bindurl ^https://duckduckgo.com f hint -Jc [data-testid="result-title-a"] +bindurl ^https://duckduckgo.com F hint -Jbc [data-testid="result-title-a"] " Only hint item pages on Hacker News bindurl news.ycombinator.com ;f hint -Jc .age > a diff --git a/modules/home/gdb/default.nix b/modules/home/gdb/default.nix index 1ffc6bd..ab51938 100644 --- a/modules/home/gdb/default.nix +++ b/modules/home/gdb/default.nix @@ -6,29 +6,27 @@ in options.my.home.gdb = with lib; { enable = my.mkDisableOption "gdb configuration"; - package = mkPackageOption pkgs "gdb" { }; - rr = { enable = my.mkDisableOption "rr configuration"; - package = mkPackageOption pkgs "rr" { }; + package = mkOption { + type = types.package; + default = pkgs.rr; + defaultText = literalExample "pkgs.rr"; + description = '' + Package providing rr + ''; + }; }; }; config = lib.mkIf cfg.enable (lib.mkMerge [ { home.packages = with pkgs; [ - cfg.package + gdb ]; - xdg = { - configFile."gdb/gdbinit".source = ./gdbinit; - stateFile."gdb/.keep".text = ""; - }; - - home.sessionVariables = { - GDBHISTFILE = "${config.xdg.stateHome}/gdb/gdb_history"; - }; + xdg.configFile."gdb/gdbinit".source = ./gdbinit; } (lib.mkIf cfg.rr.enable { diff --git a/modules/home/git/default.nix b/modules/home/git/default.nix index c3a51a0..9c10257 100644 --- a/modules/home/git/default.nix +++ b/modules/home/git/default.nix @@ -21,31 +21,57 @@ in config.programs.git = lib.mkIf cfg.enable { enable = true; + # Who am I? + userEmail = mkMailAddress "bruno" "belanyi.fr"; + userName = "Bruno BELANYI"; + inherit (cfg) package; + aliases = { + git = "!git"; + lol = "log --graph --decorate --pretty=oneline --abbrev-commit --topo-order"; + lola = "lol --all"; + assume = "update-index --assume-unchanged"; + unassume = "update-index --no-assume-unchanged"; + assumed = "!git ls-files -v | grep ^h | cut -c 3-"; + 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; + delta = { + enable = true; + + options = { + features = "diff-highlight decorations"; + + # Less jarring style for `diff-highlight` emulation + diff-highlight = { + minus-style = "red"; + minus-non-emph-style = "red"; + minus-emph-style = "bold red 52"; + + plus-style = "green"; + plus-non-emph-style = "green"; + plus-emph-style = "bold green 22"; + + whitespace-error-style = "reverse red"; + }; + + # Personal preference for easier reading + decorations = { + commit-style = "raw"; # Do not recolor meta information + keep-plus-minus-markers = true; + paging = "always"; + }; + }; + }; + # There's more - settings = { - # Who am I? - user = { - email = mkMailAddress "bruno" "belanyi.fr"; - name = "Bruno BELANYI"; - }; - - alias = { - git = "!git"; - lol = "log --graph --decorate --pretty=oneline --abbrev-commit --topo-order"; - lola = "lol --all"; - assume = "update-index --assume-unchanged"; - unassume = "update-index --no-assume-unchanged"; - assumed = "!git ls-files -v | grep ^h | cut -c 3-"; - pick = "log -p -G"; - push-new = "!git push -u origin " - + ''"$(git branch | grep '^* ' | cut -f2- -d' ')"''; - root = "git rev-parse --show-toplevel"; - }; - + extraConfig = { # Makes it a bit more readable blame = { coloring = "repeatedLines"; @@ -97,6 +123,11 @@ in defaultBranch = "main"; }; + # Local configuration, not-versioned + include = { + path = "config.local"; + }; + merge = { conflictStyle = "zdiff3"; }; @@ -117,10 +148,6 @@ in autoStash = true; }; - rerere = { - enabled = true; - }; - url = { "git@git.belanyi.fr:" = { insteadOf = "https://git.belanyi.fr/"; @@ -136,8 +163,8 @@ in }; }; - includes = lib.mkAfter [ - # Multiple identities + # Multiple identities + includes = [ { condition = "gitdir:~/git/EPITA/"; contents = { @@ -156,10 +183,6 @@ in }; }; } - # Local configuration, not-versioned - { - path = "config.local"; - } ]; ignores = diff --git a/modules/home/gpg/default.nix b/modules/home/gpg/default.nix index 2a00baf..7eadf48 100644 --- a/modules/home/gpg/default.nix +++ b/modules/home/gpg/default.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, ... }: +{ config, lib, ... }: let cfg = config.my.home.gpg; in @@ -6,7 +6,12 @@ in options.my.home.gpg = with lib; { enable = my.mkDisableOption "gpg configuration"; - pinentry = mkPackageOption pkgs "pinentry" { default = [ "pinentry-tty" ]; }; + pinentry = mkOption { + type = types.str; + default = "tty"; + example = "gtk2"; + description = "Which pinentry interface to use"; + }; }; config = lib.mkIf cfg.enable { @@ -17,7 +22,7 @@ in services.gpg-agent = { enable = true; enableSshSupport = true; # One agent to rule them all - pinentry.package = cfg.pinentry; + pinentryFlavor = cfg.pinentry; extraConfig = '' allow-loopback-pinentry ''; diff --git a/modules/home/gtk/default.nix b/modules/home/gtk/default.nix index f10087d..62d3f81 100644 --- a/modules/home/gtk/default.nix +++ b/modules/home/gtk/default.nix @@ -21,12 +21,12 @@ in }; iconTheme = { - package = pkgs.gnome-themes-extra; + package = pkgs.gnome.gnome-themes-extra; name = "Adwaita"; }; theme = { - package = pkgs.gnome-themes-extra; + package = pkgs.gnome.gnome-themes-extra; name = "Adwaita"; }; }; diff --git a/modules/home/jq/default.nix b/modules/home/jq/default.nix index 53e5986..57e266f 100644 --- a/modules/home/jq/default.nix +++ b/modules/home/jq/default.nix @@ -17,7 +17,6 @@ in strings = "0;32"; arrays = "1;39"; objects = "1;39"; - objectKeys = "1;34"; }; }; } diff --git a/modules/home/mail/accounts/default.nix b/modules/home/mail/accounts/default.nix index 5216ad5..8886139 100644 --- a/modules/home/mail/accounts/default.nix +++ b/modules/home/mail/accounts/default.nix @@ -26,7 +26,20 @@ let }; migaduConfig = { - flavor = "migadu.com"; + imap = { + host = "imap.migadu.com"; + port = 993; + tls = { + enable = true; + }; + }; + smtp = { + host = "smtp.migadu.com"; + port = 465; + tls = { + enable = true; + }; + }; }; gmailConfig = { @@ -45,7 +58,7 @@ in { config.accounts.email.accounts = { personal = lib.mkMerge [ - # Common configuration + # Common configuraton (mkConfig { domain = "belanyi.fr"; address = "bruno"; @@ -57,7 +70,7 @@ in ]; gmail = lib.mkMerge [ - # Common configuration + # Common configuraton (mkConfig { domain = "gmail.com"; address = "brunobelanyi"; diff --git a/modules/home/nix/default.nix b/modules/home/nix/default.nix index 2f435a8..8e777da 100644 --- a/modules/home/nix/default.nix +++ b/modules/home/nix/default.nix @@ -12,7 +12,7 @@ let # Use pinned nixpkgs when using `nix run pkgs#` pkgs = inputs.nixpkgs; } - (lib.optionalAttrs cfg.inputs.overrideNixpkgs { + (lib.optionalAttrs cfg.overrideNixpkgs { # ... And with `nix run nixpkgs#` nixpkgs = inputs.nixpkgs; }) @@ -22,30 +22,20 @@ in options.my.home.nix = with lib; { enable = my.mkDisableOption "nix configuration"; - gc = { - enable = my.mkDisableOption "nix GC configuration"; - }; + linkInputs = my.mkDisableOption "link inputs to `$XDG_CONFIG_HOME/nix/inputs`"; - cache = { - selfHosted = my.mkDisableOption "self-hosted cache"; - }; + addToRegistry = my.mkDisableOption "add inputs and self to registry"; - inputs = { - link = my.mkDisableOption "link inputs to `$XDG_CONFIG_HOME/nix/inputs/`"; + addToNixPath = my.mkDisableOption "add inputs and self to nix path"; - 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"; - }; + overrideNixpkgs = my.mkDisableOption "point nixpkgs to pinned system version"; }; config = lib.mkIf cfg.enable (lib.mkMerge [ { assertions = [ { - assertion = cfg.inputs.addToNixPath -> cfg.inputs.link; + assertion = cfg.addToNixPath -> cfg.linkInputs; message = '' enabling `my.home.nix.addToNixPath` needs to have `my.home.nix.linkInputs = true` @@ -58,43 +48,17 @@ in nix = { package = lib.mkDefault pkgs.nix; # NixOS module sets it unconditionally + # FIXME: waiting on https://github.com/nix-community/home-manager/pull/3876 settings = { + # I like XDG-compliance + use-xdg-base-directories = true; + experimental-features = [ "nix-command" "flakes" ]; }; }; } - (lib.mkIf cfg.gc.enable { - nix.gc = { - automatic = true; - - # Every week, with some wiggle room - dates = "weekly"; - randomizedDelaySec = "10min"; - - # Use a persistent timer for e.g: laptops - persistent = true; - - # Delete old profiles automatically after 15 days - options = "--delete-older-than 15d"; - }; - }) - - (lib.mkIf cfg.cache.selfHosted { - nix = { - settings = { - extra-substituters = [ - "https://cache.belanyi.fr/" - ]; - - extra-trusted-public-keys = [ - "cache.belanyi.fr:LPhrTqufwfxTceg1nRWueDWf7/2zSVY9K00pq2UI7tw=" - ]; - }; - }; - }) - - (lib.mkIf cfg.inputs.addToRegistry { + (lib.mkIf cfg.addToRegistry { nix.registry = let makeEntry = v: { flake = v; }; @@ -103,7 +67,7 @@ in makeEntries channels; }) - (lib.mkIf cfg.inputs.link { + (lib.mkIf cfg.linkInputs { xdg.configFile = let makeLink = n: v: { @@ -115,8 +79,8 @@ in makeLinks channels; }) - (lib.mkIf cfg.inputs.addToNixPath { - nix.nixPath = [ "${config.xdg.configHome}/nix/inputs" ]; + (lib.mkIf cfg.addToNixPath { + home.sessionVariables.NIX_PATH = "${config.xdg.configHome}/nix/inputs\${NIX_PATH:+:$NIX_PATH}"; }) ]); } diff --git a/modules/home/packages/default.nix b/modules/home/packages/default.nix index 43f7111..1362a06 100644 --- a/modules/home/packages/default.nix +++ b/modules/home/packages/default.nix @@ -1,7 +1,6 @@ -{ config, lib, pkgs, osConfig, ... }: +{ config, lib, pkgs, ... }: let cfg = config.my.home.packages; - useGlobalPkgs = osConfig.home-manager.useGlobalPkgs or false; in { options.my.home.packages = with lib; { @@ -27,10 +26,9 @@ in fd file ripgrep - tree ] ++ cfg.additionalPackages); - nixpkgs.config = lib.mkIf (!useGlobalPkgs) { + nixpkgs.config = { inherit (cfg) allowAliases allowUnfree; }; }; diff --git a/modules/home/pager/default.nix b/modules/home/pager/default.nix index e84dcb7..aa72587 100644 --- a/modules/home/pager/default.nix +++ b/modules/home/pager/default.nix @@ -15,12 +15,7 @@ in # Clear the screen on start and exit LESS = "-R -+X -c"; # Better XDG compliance - LESSHISTFILE = "${config.xdg.stateHome}/less/history"; + LESSHISTFILE = "${config.xdg.dataHome}/less/history"; }; - - xdg.configFile."lesskey".text = '' - # Quit without clearing the screen on `Q` - Q toggle-option -!^Predraw-on-quit\nq - ''; }; } diff --git a/modules/home/secrets/github/token.age b/modules/home/secrets/github/token.age index 3e8bb5a..1d36ccd 100644 Binary files a/modules/home/secrets/github/token.age and b/modules/home/secrets/github/token.age differ diff --git a/modules/home/secrets/secrets.nix b/modules/home/secrets/secrets.nix index 27cdb4e..f474342 100644 --- a/modules/home/secrets/secrets.nix +++ b/modules/home/secrets/secrets.nix @@ -1,6 +1,6 @@ # Common secrets let - keys = import ../../../keys; + keys = import ../../keys; all = builtins.attrValues keys.users; in diff --git a/modules/home/ssh/default.nix b/modules/home/ssh/default.nix index b0b4167..674cf6a 100644 --- a/modules/home/ssh/default.nix +++ b/modules/home/ssh/default.nix @@ -17,7 +17,6 @@ in { programs.ssh = { enable = true; - enableDefaultConfig = false; includes = [ # Local configuration, not-versioned @@ -50,16 +49,15 @@ in }; porthos = { - hostname = "37.187.146.15"; + hostname = "91.121.177.163"; identityFile = "~/.ssh/shared_rsa"; user = "ambroisie"; }; - - # `*` is automatically made the last match block by the module - "*" = { - addKeysToAgent = "yes"; - }; }; + + extraConfig = '' + AddKeysToAgent yes + ''; }; } diff --git a/modules/home/tmux/default.nix b/modules/home/tmux/default.nix index e3e3daf..08aeb55 100644 --- a/modules/home/tmux/default.nix +++ b/modules/home/tmux/default.nix @@ -5,14 +5,6 @@ let config.my.home.x.enable (config.my.home.wm.windowManager != null) ]; - - mkTerminalFeature = opt: flag: - let - mkFlag = term: ''set -as terminal-features ",${term}:${flag}"''; - enabledTerminals = lib.filterAttrs (_: v: v.${opt}) cfg.terminalFeatures; - terminals = lib.attrNames enabledTerminals; - in - lib.concatMapStringsSep "\n" mkFlag terminals; in { options.my.home.tmux = with lib; { @@ -20,24 +12,16 @@ in enablePassthrough = mkEnableOption "tmux DCS passthrough sequence"; - enableResurrect = mkEnableOption "tmux-resurrect plugin"; - - terminalFeatures = mkOption { - type = with types; attrsOf (submodule { - options = { - hyperlinks = my.mkDisableOption "hyperlinks through OSC8"; - - trueColor = my.mkDisableOption "24-bit (RGB) color support"; - }; - }); - - default = { ${config.my.home.terminal.program} = { }; }; - defaultText = literalExpression '' - { ''${config.my.home.terminal.program} = { }; }; + trueColorTerminals = mkOption { + type = with types; listOf str; + default = lib.my.nullableToList config.my.home.terminal.program; + defaultText = '' + `[ config.my.home.terminal.program ]` if it is non-null, otherwise an + empty list. ''; - example = { xterm-256color = { }; }; + example = [ "xterm-256color" ]; description = '' - $TERM values which should be considered to have additional features. + $TERM values which should be considered to always support 24-bit color. ''; }; }; @@ -48,21 +32,18 @@ in keyMode = "vi"; # Home-row keys and other niceties clock24 = true; # I'm one of those heathens escapeTime = 0; # Let vim do its thing instead - historyLimit = 1000000; # Bigger buffer - mouse = false; # I dislike mouse support - focusEvents = true; # Report focus events + historyLimit = 50000; # Bigger buffer terminal = "tmux-256color"; # I want accurate termcap info - aggressiveResize = true; # Automatic resize when switching client size - plugins = with pkgs.tmuxPlugins; builtins.filter (attr: attr != { }) [ + plugins = with pkgs.tmuxPlugins; [ # Open high-lighted files in copy mode open # Better pane management pain-control # Better session management sessionist - # X clipboard integration { + # X clipboard integration plugin = yank; extraConfig = '' # Use 'clipboard' because of misbehaving apps (e.g: firefox) @@ -71,8 +52,8 @@ in set -g @yank_action 'copy-pipe' ''; } - # Show when prefix has been pressed { + # Show when prefix has been pressed plugin = prefix-highlight; extraConfig = '' # Also show when I'm in copy or sync mode @@ -82,23 +63,9 @@ in set -g status-right '#{prefix_highlight} %a %Y-%m-%d %H:%M' ''; } - # Resurrect sessions - (lib.optionalAttrs cfg.enableResurrect { - plugin = resurrect; - extraConfig = '' - set -g @resurrect-dir '${config.xdg.stateHome}/tmux/resurrect' - ''; - }) ]; extraConfig = '' - # Refresh configuration - bind-key -N "Source tmux.conf" R source-file ${config.xdg.configHome}/tmux/tmux.conf \; display-message "Sourced tmux.conf!" - - # Accept sloppy Ctrl key when switching windows, on top of default mapping - bind-key -N "Select the previous window" C-p previous-window - bind-key -N "Select the next window" C-n next-window - # Better vim mode bind-key -T copy-mode-vi 'v' send -X begin-selection ${ @@ -122,10 +89,13 @@ in '' } - # Force OSC8 hyperlinks for each relevant $TERM - ${mkTerminalFeature "hyperlinks" "hyperlinks"} # Force 24-bit color for each relevant $TERM - ${mkTerminalFeature "trueColor" "RGB"} + ${ + let + mkTcFlag = term: ''set -as terminal-features ",${term}:RGB"''; + in + lib.concatMapStringsSep "\n" mkTcFlag cfg.trueColorTerminals + } ''; }; } diff --git a/modules/home/trgui/default.nix b/modules/home/trgui/default.nix deleted file mode 100644 index ee545a9..0000000 --- a/modules/home/trgui/default.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ config, lib, pkgs, ... }: -let - cfg = config.my.home.trgui; -in -{ - options.my.home.trgui = with lib; { - enable = mkEnableOption "Transmission GUI onfiguration"; - - package = mkPackageOption pkgs "TrguiNG" { default = "trgui-ng"; }; - }; - - config = lib.mkIf cfg.enable { - home.packages = with pkgs; [ - cfg.package - ]; - }; -} diff --git a/modules/home/vim/after/ftplugin/json.vim b/modules/home/vim/after/ftplugin/json.vim deleted file mode 100644 index 3f7b09d..0000000 --- a/modules/home/vim/after/ftplugin/json.vim +++ /dev/null @@ -1,6 +0,0 @@ -" Create the `b:undo_ftplugin` variable if it doesn't exist -call ftplugined#check_undo_ft() - -" Use a small indentation value on JSON files -setlocal shiftwidth=2 -let b:undo_ftplugin.='|setlocal shiftwidth<' diff --git a/modules/home/vim/after/ftplugin/netrw.vim b/modules/home/vim/after/ftplugin/netrw.vim new file mode 100644 index 0000000..e3689f8 --- /dev/null +++ b/modules/home/vim/after/ftplugin/netrw.vim @@ -0,0 +1,6 @@ +" Create the `b:undo_ftplugin` variable if it doesn't exist +call ftplugined#check_undo_ft() + +" Don't show Netrw in buffer list +setlocal bufhidden=delete +let b:undo_ftplugin='|setlocal bufhidden<' diff --git a/modules/home/vim/after/ftplugin/query.vim b/modules/home/vim/after/ftplugin/query.vim deleted file mode 100644 index fd2ac73..0000000 --- a/modules/home/vim/after/ftplugin/query.vim +++ /dev/null @@ -1,6 +0,0 @@ -" Create the `b:undo_ftplugin` variable if it doesn't exist -call ftplugined#check_undo_ft() - -" Use a small indentation value on query files -setlocal shiftwidth=2 -let b:undo_ftplugin.='|setlocal shiftwidth<' diff --git a/modules/home/vim/after/plugin/mappings/commentary.lua b/modules/home/vim/after/plugin/mappings/commentary.lua new file mode 100644 index 0000000..6ed3b89 --- /dev/null +++ b/modules/home/vim/after/plugin/mappings/commentary.lua @@ -0,0 +1,10 @@ +local wk = require("which-key") + +local keys = { + name = "Comment/uncomment", + c = "Current line", + u = "Uncomment the current and adjacent commented lines", + ["gc"] = "Uncomment the current and adjacent commented lines", +} + +wk.register(keys, { prefix = "gc" }) diff --git a/modules/home/vim/after/plugin/mappings/misc.lua b/modules/home/vim/after/plugin/mappings/misc.lua new file mode 100644 index 0000000..6aa25a2 --- /dev/null +++ b/modules/home/vim/after/plugin/mappings/misc.lua @@ -0,0 +1,7 @@ +local wk = require("which-key") + +local keys = { + [""] = { "nohls", "Clear search highlight" }, +} + +wk.register(keys, { prefix = "" }) diff --git a/modules/home/vim/after/plugin/mappings/telescope.lua b/modules/home/vim/after/plugin/mappings/telescope.lua new file mode 100644 index 0000000..0867b36 --- /dev/null +++ b/modules/home/vim/after/plugin/mappings/telescope.lua @@ -0,0 +1,15 @@ +local wk = require("which-key") +local telescope_builtin = require("telescope.builtin") + +local keys = { + f = { + name = "Fuzzy finder", + b = { telescope_builtin.buffers, "Open buffers" }, + f = { telescope_builtin.git_files, "Git tracked files" }, + F = { telescope_builtin.find_files, "Files" }, + g = { telescope_builtin.live_grep, "Grep string" }, + G = { telescope_builtin.grep_string, "Grep string under cursor" }, + }, +} + +wk.register(keys, { prefix = "" }) diff --git a/modules/home/vim/after/plugin/mappings/tree-sitter-textobjects.lua b/modules/home/vim/after/plugin/mappings/tree-sitter-textobjects.lua new file mode 100644 index 0000000..631731c --- /dev/null +++ b/modules/home/vim/after/plugin/mappings/tree-sitter-textobjects.lua @@ -0,0 +1,30 @@ +local wk = require("which-key") + +local motions = { + ["]m"] = "Next method start", + ["]M"] = "Next method end", + ["]S"] = "Next statement start", + ["]]"] = "Next class start", + ["]["] = "Next class end", + ["[m"] = "Previous method start", + ["[M"] = "Previous method end", + ["[S"] = "Previous statement start", + ["[["] = "Previous class start", + ["[]"] = "Previous class end", +} + +local objects = { + ["aa"] = "a parameter", + ["ia"] = "inner parameter", + ["ab"] = "a block", + ["ib"] = "inner block", + ["ac"] = "a class", + ["ic"] = "inner class", + ["af"] = "a function", + ["if"] = "inner function", + ["ak"] = "a comment", + ["aS"] = "a statement", +} + +wk.register(motions, { mode = "n" }) +wk.register(objects, { mode = "o" }) diff --git a/modules/home/vim/after/plugin/mappings/unimpaired.lua b/modules/home/vim/after/plugin/mappings/unimpaired.lua index 765b6b1..f502056 100644 --- a/modules/home/vim/after/plugin/mappings/unimpaired.lua +++ b/modules/home/vim/after/plugin/mappings/unimpaired.lua @@ -3,120 +3,126 @@ local wk = require("which-key") local lsp = require("ambroisie.lsp") local keys = { - -- Previous - { "[", group = "Previous" }, - -- Edition and navigation mappings - { "[", desc = "Insert blank line above" }, - { "[", desc = "Previous location list file" }, - { "[", desc = "Previous quickfix list file" }, - { "[", desc = "Previous tag in preview window" }, - { "[a", desc = "Previous argument" }, - { "[A", desc = "First argument" }, - { "[b", desc = "Previous buffer" }, - { "[B", desc = "First buffer" }, - { "[e", desc = "Exchange previous line" }, - { "[f", desc = "Previous file in directory" }, - { "[l", desc = "Previous location list entry" }, - { "[L", desc = "First Location list entry" }, - { "[n", desc = "Previous conflict marker/diff hunk" }, - { "[p", desc = "Paste line above" }, - { "[P", desc = "Paste line above" }, - { "[q", desc = "Previous quickfix list entry" }, - { "[Q", desc = "First quickfix list entry" }, - { "[t", desc = "Previous matching tag" }, - { "[T", desc = "First matching tag" }, - { "[z", desc = "Previous fold" }, - -- Encoding - { "[C", desc = "C string encode" }, - { "[u", desc = "URL encode" }, - { "[x", desc = "XML encode" }, - { "[y", desc = "C string encode" }, + -- Edition and navigation mappins + ["["] = { + name = "Previous", + [""] = "Insert blank line above", + [""] = "Previous location list file", + [""] = "Previous quickfix list file", + [""] = "Previous tag in preview window", + a = "Previous argument", + A = "First argument", + b = "Previous buffer", + B = "First buffer", + e = "Exchange previous line", + f = "Previous file in directory", + l = "Previous location list entry", + L = "First Location list entry", + n = "Previous conflict marker/diff hunk", + p = "Paste line above", + P = "Paste line above", + q = "Previous quickfix list entry", + Q = "First quickfix list entry", + t = "Previous matching tag", + T = "First matching tag", + z = "Previous fold", + -- Encoding + C = "C string encode", + u = "URL encode", + x = "XML encode", + y = "C string encode", + -- Custom + d = { lsp.goto_prev_diagnostic, "Previous diagnostic" }, + }, + ["]"] = { + name = "Next", + [""] = "Insert blank line below", + [""] = "Next location list file", + [""] = "Next quickfix list file", + [""] = "Next tag in preview window", + a = "Next argument", + A = "Last argument", + b = "Next buffer", + B = "Last buffer", + e = "Exchange next line", + f = "Next file in directory", + l = "Next location list entry", + L = "Last Location list entry", + n = "Next conflict marker/diff hunk", + p = "Paste line below", + P = "Paste line below", + q = "Next quickfix list entry", + Q = "Last quickfix list entry", + t = "Next matching tag", + T = "Last matching tag", + z = "Next fold", + -- Decoding + C = "C string decode", + u = "URL decode", + x = "XML decode", + y = "C string decode", + -- Custom + d = { lsp.goto_next_diagnostic, "Next diagnostic" }, + }, - -- Next - { "]", group = "Next" }, - -- Edition and navigation mappings - { "]", desc = "Insert blank line below" }, - { "]", desc = "Next location list file" }, - { "]", desc = "Next quickfix list file" }, - { "]", desc = "Next tag in preview window" }, - { "]a", desc = "Next argument" }, - { "]A", desc = "Last argument" }, - { "]b", desc = "Next buffer" }, - { "]B", desc = "Last buffer" }, - { "]e", desc = "Exchange next line" }, - { "]f", desc = "Next file in directory" }, - { "]l", desc = "Next location list entry" }, - { "]L", desc = "Last Location list entry" }, - { "]n", desc = "Next conflict marker/diff hunk" }, - { "]p", desc = "Paste line below" }, - { "]P", desc = "Paste line below" }, - { "]q", desc = "Next quickfix list entry" }, - { "]Q", desc = "Last quickfix list entry" }, - { "]t", desc = "Next matching tag" }, - { "]T", desc = "Last matching tag" }, - { "]z", desc = "Next fold" }, - -- Decoding - { "]C", desc = "C string decode" }, - { "]u", desc = "URL decode" }, - { "]x", desc = "XML decode" }, - { "]y", desc = "C string decode" }, - - -- Enable option - { "[o", group = "Enable option" }, - { "[ob", desc = "Light background" }, - { "[oc", desc = "Cursor line" }, - { "[od", desc = "Diff" }, - { "[of", "FormatEnable", desc = "LSP Formatting" }, - { "[oh", desc = "Search high-lighting" }, - { "[oi", desc = "Case insensitive search" }, - { "[ol", desc = "List mode" }, - { "[on", desc = "Line numbers" }, - { "[or", desc = "Relative line numbers" }, - { "[op", "lwindow", desc = "Location list" }, - { "[oq", "cwindow", desc = "Quickfix list" }, - { "[ou", desc = "Cursor column" }, - { "[ov", desc = "Virtual editing" }, - { "[ow", desc = "Text wrapping" }, - { "[ox", desc = "Cursor line and column" }, - { "[oz", desc = "Spell checking" }, - - -- Disable option - { "]o", group = "Disable option" }, - { "]ob", desc = "Light background" }, - { "]oc", desc = "Cursor line" }, - { "]od", desc = "Diff" }, - { "]of", "FormatDisable", desc = "LSP Formatting" }, - { "]oh", desc = "Search high-lighting" }, - { "]oi", desc = "Case insensitive search" }, - { "]ol", desc = "List mode" }, - { "]on", desc = "Line numbers" }, - { "]op", "lclose", desc = "Location list" }, - { "]oq", "cclose", desc = "Quickfix list" }, - { "]or", desc = "Relative line numbers" }, - { "]ou", desc = "Cursor column" }, - { "]ov", desc = "Virtual editing" }, - { "]ow", desc = "Text wrapping" }, - { "]ox", desc = "Cursor line and column" }, - { "]oz", desc = "Spell checking" }, - - -- Toggle option - { "yo", group = "Toggle option" }, - { "yob", desc = "Light background" }, - { "yoc", desc = "Cursor line" }, - { "yod", desc = "Diff" }, - { "yof", "FormatToggle", desc = "LSP Formatting" }, - { "yoh", desc = "Search high-lighting" }, - { "yoi", desc = "Case insensitive search" }, - { "yol", desc = "List mode" }, - { "yon", desc = "Line numbers" }, - { "yop", "(qf_loc_toggle)", desc = "Location list" }, - { "yoq", "(qf_qf_toggle)", desc = "Quickfix list" }, - { "yor", desc = "Relative line numbers" }, - { "you", desc = "Cursor column" }, - { "yov", desc = "Virtual editing" }, - { "yow", desc = "Text wrapping" }, - { "yox", desc = "Cursor line and column" }, - { "yoz", desc = "Spell checking" }, + -- Option mappings + ["[o"] = { + name = "Enable option", + b = "Light background", + c = "Cursor line", + d = "Diff", + 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", + x = "Cursor line and column", + z = "Spell checking", + }, + ["]o"] = { + name = "Option off", + b = "Light background", + c = "Cursor line", + d = "Diff", + 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", + w = "Text wrapping", + x = "Cursor line and column", + z = "Spell checking", + }, + ["yo"] = { + name = "Option toggle", + b = "Light background", + c = "Cursor line", + d = "Diff", + 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", + w = "Text wrapping", + x = "Cursor line and column", + z = "Spell checking", + }, } -wk.add(keys) +wk.register(keys) diff --git a/modules/home/vim/after/queries/diff/highlights.scm b/modules/home/vim/after/queries/diff/highlights.scm deleted file mode 100644 index c998725..0000000 --- a/modules/home/vim/after/queries/diff/highlights.scm +++ /dev/null @@ -1,5 +0,0 @@ -; extends - -; I want to the line added/removed markers to be the correct color -"+" @diff.plus -"-" @diff.minus diff --git a/modules/home/vim/after/queries/gitcommit/highlights.scm b/modules/home/vim/after/queries/gitcommit/highlights.scm deleted file mode 100644 index 05162c9..0000000 --- a/modules/home/vim/after/queries/gitcommit/highlights.scm +++ /dev/null @@ -1,6 +0,0 @@ -; extends - -; Highlight over-extended subject lines (rely on wrapping for message body) -((subject) @comment.error - (#vim-match? @comment.error ".\{50,}") - (#offset! @comment.error 0 50 0 0)) diff --git a/modules/home/vim/default.nix b/modules/home/vim/default.nix index 930a853..871bf40 100644 --- a/modules/home/vim/default.nix +++ b/modules/home/vim/default.nix @@ -40,18 +40,25 @@ in lualine-lsp-progress # Show progress for LSP servers # tpope essentials + vim-commentary # Easy comments vim-eunuch # UNIX integrations vim-fugitive # A 'git' wrapper vim-git # Sane git syntax files vim-repeat # Enanche '.' for plugins vim-rsi # Readline mappings vim-unimpaired # Some ex command mappings + vim-vinegar # Better netrw # Languages + rust-vim vim-beancount + vim-jsonnet + vim-nix + 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 @@ -59,13 +66,16 @@ in # LSP and linting nvim-lspconfig # Easy LSP configuration lsp-format-nvim # Simplified formatting configuration + lsp_lines-nvim # Show diagnostics *over* regions none-ls-nvim # LSP integration for linters and formatters nvim-treesitter.withAllGrammars # Better highlighting nvim-treesitter-textobjects # More textobjects + 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-async-path # More responsive path completion cmp-buffer # Words from open buffers @@ -78,8 +88,8 @@ in dressing-nvim # Integrate native UI hooks with Telescope etc... gitsigns-nvim # Fast git UI integration nvim-surround # Deal with pairs, now in Lua - oil-nvim # Better alternative to NetrW telescope-fzf-native-nvim # Use 'fzf' fuzzy matching algorithm + telescope-lsp-handlers-nvim # Use 'telescope' for various LSP actions telescope-nvim # Fuzzy finder interface which-key-nvim # Show available mappings ]; @@ -95,11 +105,8 @@ in nixpkgs-fmt # Shell - bash-language-server + shellcheck shfmt - - # Generic - typos-lsp ]; }; diff --git a/modules/home/vim/ftdetect/glsl.lua b/modules/home/vim/ftdetect/glsl.lua new file mode 100644 index 0000000..2f4f1dd --- /dev/null +++ b/modules/home/vim/ftdetect/glsl.lua @@ -0,0 +1,7 @@ +-- Use GLSL filetype for common shader file extensions +vim.filetype.add({ + extension = { + frag = "glsl", + vert = "glsl", + }, +}) diff --git a/modules/home/vim/ftdetect/gn.lua b/modules/home/vim/ftdetect/gn.lua new file mode 100644 index 0000000..37d772e --- /dev/null +++ b/modules/home/vim/ftdetect/gn.lua @@ -0,0 +1,7 @@ +-- Use GN filetype for Chromium Generate Ninja files +vim.filetype.add({ + extension = { + gn = "gn", + gni = "gn", + }, +}) diff --git a/modules/home/vim/ftdetect/kbuild.lua b/modules/home/vim/ftdetect/kbuild.lua new file mode 100644 index 0000000..799570e --- /dev/null +++ b/modules/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/modules/home/vim/ftdetect/tikz.lua b/modules/home/vim/ftdetect/tikz.lua new file mode 100644 index 0000000..93b7db0 --- /dev/null +++ b/modules/home/vim/ftdetect/tikz.lua @@ -0,0 +1,6 @@ +-- Use LaTeX filetype for TikZ files +vim.filetype.add({ + extension = { + tikz = "tex", + }, +}) diff --git a/modules/home/vim/init.vim b/modules/home/vim/init.vim index 1142925..bd63d25 100644 --- a/modules/home/vim/init.vim +++ b/modules/home/vim/init.vim @@ -1,4 +1,4 @@ -" Basic configuration {{{ +" Basic configuraion {{{ """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Use UTF-8 set encoding=utf-8 @@ -38,10 +38,10 @@ set tabstop=8 " File parameters {{{ """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" Disable swap files +" Disable backups, we have source control for that +set nobackup +" Disable swapfiles too set noswapfile -" Enable undo files -set undofile " }}} " UI and UX parameters {{{ @@ -68,6 +68,8 @@ 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 @@ -81,29 +83,11 @@ set updatetime=250 " Disable all mouse integrations set mouse= -" Setup some overrides for gruvbox -lua << EOF -local gruvbox = require("gruvbox") -local colors = gruvbox.palette +" Set dark mode by default +set background=dark -gruvbox.setup({ - overrides = { - -- Only URLs should be underlined - ["@string.special.path"] = { link = "GruvboxOrange" }, - -- Revert back to the better diff highlighting - DiffAdd = { fg = colors.green, bg = "NONE" }, - DiffChange = { fg = colors.aqua, bg = "NONE" }, - DiffDelete = { fg = colors.red, bg = "NONE" }, - DiffText = { fg = colors.yellow, bg = colors.bg0 }, - -- Directories "pop" better in blue - Directory = { link = "GruvboxBlueBold" }, - }, - italic = { - -- Comments should not be italic, for e.g: box drawing - comments = false, - }, -}) -EOF +" 24 bit colors +set termguicolors " Use my preferred colorscheme colorscheme gruvbox " }}} diff --git a/modules/home/vim/lua/ambroisie/lsp.lua b/modules/home/vim/lua/ambroisie/lsp.lua index fef0487..99d8dab 100644 --- a/modules/home/vim/lua/ambroisie/lsp.lua +++ b/modules/home/vim/lua/ambroisie/lsp.lua @@ -3,9 +3,46 @@ 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 attached client +--- @param bufnr int? buffer number of the attched client M.on_attach = function(client, bufnr) -- Format on save lsp_format.on_attach(client, bufnr) @@ -14,7 +51,8 @@ M.on_attach = function(client, bufnr) local wk = require("which-key") local function list_workspace_folders() - vim.print(vim.lsp.buf.list_workspace_folders()) + local utils = require("ambroisie.utils") + utils.dump(vim.lsp.buf.list_workspace_folders()) end local function cycle_diagnostics_display() @@ -42,10 +80,6 @@ M.on_attach = function(client, bufnr) vim.diagnostic.config({ virtual_text = text, virtual_lines = lines, - jump = { - -- Show float on jump if no diagnostic text is otherwise shown - float = not (text or lines), - }, }) end @@ -53,36 +87,32 @@ M.on_attach = function(client, bufnr) vim.diagnostic.open_float(nil, { scope = "buffer" }) end - local function toggle_inlay_hints() - vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) - end - local keys = { - buffer = bufnr, - -- LSP navigation - { "K", vim.lsp.buf.hover, desc = "Show symbol information" }, - { "", vim.lsp.buf.signature_help, desc = "Show signature information" }, - { "gd", vim.lsp.buf.definition, desc = "Go to definition" }, - { "gD", vim.lsp.buf.declaration, desc = "Go to declaration" }, - { "gi", vim.lsp.buf.implementation, desc = "Go to implementation" }, - { "gr", vim.lsp.buf.references, desc = "List all references" }, - -- Code - { "c", group = "Code" }, - { "ca", vim.lsp.buf.code_action, desc = "Code actions" }, - { "cd", cycle_diagnostics_display, desc = "Cycle diagnostics display" }, - { "cD", show_buffer_diagnostics, desc = "Show buffer diagnostics" }, - { "ch", toggle_inlay_hints, desc = "Toggle inlay hints" }, - { "cr", vim.lsp.buf.rename, desc = "Rename symbol" }, - { "cs", vim.lsp.buf.signature_help, desc = "Show signature" }, - { "ct", vim.lsp.buf.type_definition, desc = "Go to type definition" }, - -- Workspace - { "cw", group = "Workspace" }, - { "cwa", vim.lsp.buf.add_workspace_folder, desc = "Add folder to workspace" }, - { "cwl", list_workspace_folders, desc = "List folders in workspace" }, - { "cwr", vim.lsp.buf.remove_workspace_folder, desc = "Remove folder from workspace" }, + 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" }, + ["gr"] = { vim.lsp.buf.references, "List all references" }, + + ["c"] = { + name = "Code", + a = { vim.lsp.buf.code_action, "Code actions" }, + 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" }, + t = { vim.lsp.buf.type_definition, "Go to type definition" }, + w = { + name = "Workspace", + a = { vim.lsp.buf.add_workspace_folder, "Add folder to workspace" }, + l = { list_workspace_folders, "List folders in workspace" }, + r = { vim.lsp.buf.remove_workspace_folder, "Remove folder from workspace" }, + }, + }, } - wk.add(keys) + wk.register(keys, { buffer = bufnr }) end return M diff --git a/modules/home/vim/lua/ambroisie/utils.lua b/modules/home/vim/lua/ambroisie/utils.lua index 0ee7c83..418e0d1 100644 --- a/modules/home/vim/lua/ambroisie/utils.lua +++ b/modules/home/vim/lua/ambroisie/utils.lua @@ -1,5 +1,11 @@ local M = {} +--- pretty print lua object +--- @param obj any object to pretty print +M.dump = function(obj) + print(vim.inspect(obj)) +end + --- checks if a given command is executable --- @param cmd string? command to check --- @return boolean executable @@ -9,7 +15,7 @@ end --- return a function that checks if a given command is executable --- @param cmd string? command to check ---- @return fun(): boolean executable +--- @return fun(cmd: string): boolean executable M.is_executable_condition = function(cmd) return function() return M.is_executable(cmd) @@ -34,11 +40,11 @@ M.is_ssh = function() return false end ---- list all active LSP clients for specific buffer, or all buffers +--- list all active LSP clients for current buffer --- @param bufnr int? buffer number --- @return table all active LSP client names M.list_lsp_clients = function(bufnr) - local clients = vim.lsp.get_clients({ bufnr = bufnr }) + local clients = vim.lsp.buf_get_clients(bufnr) local names = {} for _, client in ipairs(clients) do @@ -48,22 +54,4 @@ M.list_lsp_clients = function(bufnr) return names end ---- partially apply a function with given arguments -M.partial = function(f, ...) - local a = { ... } - local a_len = select("#", ...) - - return function(...) - local tmp = { ... } - local tmp_len = select("#", ...) - - -- Merge arg lists - for i = 1, tmp_len do - a[a_len + i] = tmp[i] - end - - return f(unpack(a, 1, a_len + tmp_len)) - end -end - return M diff --git a/modules/home/vim/plugin/numbertoggle.lua b/modules/home/vim/plugin/numbertoggle.lua index b1e3df2..1f97fc8 100644 --- a/modules/home/vim/plugin/numbertoggle.lua +++ b/modules/home/vim/plugin/numbertoggle.lua @@ -7,18 +7,17 @@ local numbertoggle = vim.api.nvim_create_augroup("numbertoggle", { clear = true vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "InsertLeave", "WinEnter" }, { pattern = "*", group = numbertoggle, - callback = function() - if vim.opt.number:get() then - vim.opt.relativenumber = true - end - end, + command = "if &nu | setlocal rnu | endif", }) vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter", "WinLeave" }, { pattern = "*", group = numbertoggle, - callback = function() - if vim.opt.number:get() then - vim.opt.relativenumber = false - end - end, + 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/modules/home/vim/plugin/settings/fastfold.lua b/modules/home/vim/plugin/settings/fastfold.lua new file mode 100644 index 0000000..78ee937 --- /dev/null +++ b/modules/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/modules/home/vim/plugin/settings/git.lua b/modules/home/vim/plugin/settings/git.lua index b9b92a6..4dbebca 100644 --- a/modules/home/vim/plugin/settings/git.lua +++ b/modules/home/vim/plugin/settings/git.lua @@ -1,75 +1,58 @@ local gitsigns = require("gitsigns") -local utils = require("ambroisie.utils") local wk = require("which-key") ---- Transform `f` into a function which acts on the current visual selection -local function make_visual(f) - return function() - local first = vim.fn.line("v") - local last = vim.fn.line(".") - f({ first, last }) - end -end - -local function nav_hunk(dir) - if vim.wo.diff then - local map = { - prev = "[c", - next = "]c", - } - vim.cmd.normal({ map[dir], bang = true }) - else - gitsigns.nav_hunk(dir) - end -end - gitsigns.setup({ current_line_blame_opts = { -- Show the blame quickly delay = 100, }, - -- Work-around for https://github.com/lewis6991/gitsigns.nvim/issues/929 - signs_staged_enable = false, }) local keys = { -- Navigation - { "[c", utils.partial(nav_hunk, "prev"), desc = "Previous hunk/diff" }, - { "]c", utils.partial(nav_hunk, "next"), desc = "Next hunk/diff" }, + ["[c"] = { "&diff ? '[c' : 'Gitsigns prev_hunk'", "Previous hunk/diff", expr = true }, + ["]c"] = { "&diff ? ']c' : 'Gitsigns next_hunk'", "Next hunk/diff", expr = true }, + -- Commands - { "g", group = "Git" }, - { "gb", gitsigns.toggle_current_line_blame, desc = "Toggle blame virtual text" }, - { "gd", gitsigns.diffthis, desc = "Diff buffer" }, - { "gD", utils.partial(gitsigns.diffthis, "~"), desc = "Diff buffer against last commit" }, - { "gg", "Git", desc = "Git status" }, - { "gh", gitsigns.toggle_deleted, desc = "Show deleted hunks" }, - { "gL", ":spT:Gllog --follow -- %:p", desc = "Current buffer log" }, - { "gm", "(git-messenger)", desc = "Current line blame" }, - { "gp", gitsigns.preview_hunk, desc = "Preview hunk" }, - { "gr", gitsigns.reset_hunk, desc = "Restore hunk" }, - { "gR", gitsigns.reset_buffer, desc = "Restore buffer" }, - { "gs", gitsigns.stage_hunk, desc = "Stage hunk" }, - { "gS", gitsigns.stage_buffer, desc = "Stage buffer" }, - { "gu", gitsigns.undo_stage_hunk, desc = "Undo stage hunk" }, - { "g[", utils.partial(gitsigns.nav_hunk, "prev"), desc = "Previous hunk" }, - { "g]", utils.partial(gitsigns.nav_hunk, "next"), desc = "Next hunk" }, + ["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 = { - mode = "o", - { "ih", gitsigns.select_hunk, desc = "Git hunk" }, -} --- Visual -local visual = { - mode = { "x" }, - { "ih", gitsigns.select_hunk, desc = "Git hunk" }, - { "g", group = "Git" }, - { "gp", gitsigns.preview_hunk, desc = "Preview selection" }, - { "gr", make_visual(gitsigns.reset_hunk), desc = "Restore selection" }, - { "gs", make_visual(gitsigns.stage_hunk), desc = "Stage selection" }, - { "gu", gitsigns.undo_stage_hunk, desc = "Undo stage selection" }, + ["ih"] = { gitsigns.select_hunk, "Git hunk" }, } -wk.add(keys) -wk.add(objects) -wk.add(visual) +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/modules/home/vim/plugin/settings/lsp-lines.lua b/modules/home/vim/plugin/settings/lsp-lines.lua new file mode 100644 index 0000000..9c79818 --- /dev/null +++ b/modules/home/vim/plugin/settings/lsp-lines.lua @@ -0,0 +1,3 @@ +local lsp_lines = require("lsp_lines") + +lsp_lines.setup() diff --git a/modules/home/vim/plugin/settings/lspconfig.lua b/modules/home/vim/plugin/settings/lspconfig.lua index 1596e84..794a765 100644 --- a/modules/home/vim/plugin/settings/lspconfig.lua +++ b/modules/home/vim/plugin/settings/lspconfig.lua @@ -1,3 +1,4 @@ +local lspconfig = require("lspconfig") local lsp = require("ambroisie.lsp") local utils = require("ambroisie.utils") @@ -15,57 +16,46 @@ vim.diagnostic.config({ update_in_insert = false, -- Show highest severity first severity_sort = true, - jump = { - -- Show float on diagnostic jumps - float = true, - }, }) -- Inform servers we are able to do completion, snippets, etc... local capabilities = require("cmp_nvim_lsp").default_capabilities() --- Shared configuration -vim.lsp.config("*", { - capabilities = capabilities, - on_attach = lsp.on_attach, -}) - -local servers = { - -- C/C++ - clangd = {}, - -- Haskell - hls = {}, - -- Nix - nil_ls = {}, - -- Python - pyright = {}, - ruff = {}, - -- Rust - rust_analyzer = {}, - -- Shell - bashls = { - filetypes = { "bash", "sh", "zsh" }, - settings = { - bashIde = { - shfmt = { - -- Simplify the code - simplifyCode = true, - -- Indent switch cases - caseIndent = true, - }, - }, - }, - }, - -- Starlark - starpls = {}, - -- Generic - harper_ls = {}, - typos_lsp = {}, -} - -for server, config in pairs(servers) do - if not vim.tbl_isempty(config) then - vim.lsp.config(server, config) - end - vim.lsp.enable(server) +-- C/C++ +if utils.is_executable("clangd") then + lspconfig.clangd.setup({ + capabilities = capabilities, + on_attach = lsp.on_attach, + }) +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, + on_attach = lsp.on_attach, + }) +end + +-- Python +if utils.is_executable("pyright") then + lspconfig.pyright.setup({ + capabilities = capabilities, + on_attach = lsp.on_attach, + }) +end + +-- Rust +if utils.is_executable("rust-analyzer") then + lspconfig.rust_analyzer.setup({ + capabilities = capabilities, + on_attach = lsp.on_attach, + }) end diff --git a/modules/home/vim/plugin/settings/lualine.lua b/modules/home/vim/plugin/settings/lualine.lua index bbe4647..fdaccda 100644 --- a/modules/home/vim/plugin/settings/lualine.lua +++ b/modules/home/vim/plugin/settings/lualine.lua @@ -1,5 +1,4 @@ local lualine = require("lualine") -local oil = require("oil") local utils = require("ambroisie.utils") local function list_spell_languages() @@ -11,7 +10,7 @@ local function list_spell_languages() end local function list_lsp_clients() - local client_names = utils.list_lsp_clients(0) + local client_names = utils.list_lsp_clients() if #client_names == 0 then return "" @@ -31,7 +30,7 @@ lualine.setup({ { "mode" }, }, lualine_b = { - { "branch" }, + { "FugitiveHead" }, { "filename", symbols = { readonly = "🔒" } }, }, lualine_c = { @@ -58,21 +57,5 @@ lualine.setup({ extensions = { "fugitive", "quickfix", - { - sections = { - lualine_a = { - { "mode" }, - }, - lualine_b = { - { "branch" }, - }, - lualine_c = { - function() - return vim.fn.fnamemodify(oil.get_current_dir(), ":~") - end, - }, - }, - filetypes = { "oil" }, - }, }, }) diff --git a/modules/home/vim/plugin/settings/luasnip.lua b/modules/home/vim/plugin/settings/luasnip.lua new file mode 100644 index 0000000..80309d7 --- /dev/null +++ b/modules/home/vim/plugin/settings/luasnip.lua @@ -0,0 +1 @@ +require("luasnip.loaders.from_vscode").lazy_load() diff --git a/modules/home/vim/plugin/settings/null-ls.lua b/modules/home/vim/plugin/settings/null-ls.lua index 258a209..0eaa55c 100644 --- a/modules/home/vim/plugin/settings/null-ls.lua +++ b/modules/home/vim/plugin/settings/null-ls.lua @@ -18,16 +18,48 @@ null_ls.register({ }), }) +-- C, C++ +null_ls.register({ + null_ls.builtins.formatting.clang_format.with({ + -- Only used if available, but prefer clangd formatting if available + condition = function() + return utils.is_executable("clang-format") and not utils.is_executable("clangd") + end, + }), +}) + +-- Haskell +null_ls.register({ + null_ls.builtins.formatting.brittany.with({ + -- Only used if available + condition = utils.is_executable_condition("brittany"), + }), +}) + -- Nix null_ls.register({ null_ls.builtins.formatting.nixpkgs_fmt.with({ - -- Only used if available - condition = utils.is_executable_condition("nixpkgs-fmt"), + -- Only used if available, but prefer rnix if available + condition = function() + return utils.is_executable("nixpkgs-fmt") + and not utils.is_executable("rnix-lsp") + and not utils.is_executable("nil") + end, }), }) -- 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("pflake8"), + }), null_ls.builtins.diagnostics.mypy.with({ -- Only used if available condition = utils.is_executable_condition("mypy"), @@ -46,3 +78,61 @@ null_ls.register({ condition = utils.is_executable_condition("isort"), }), }) + +-- Shell (non-POSIX) +null_ls.register({ + null_ls.builtins.code_actions.shellcheck.with({ + -- Restrict to bash and zsh + filetypes = { "bash", "zsh" }, + -- Only used if available + condition = utils.is_executable_condition("shellcheck"), + }), + null_ls.builtins.diagnostics.shellcheck.with({ + -- Show error code in message + diagnostics_format = "[#{c}] #{m}", + -- Require explicit empty string test, use bash dialect + extra_args = { "-s", "bash", "-o", "avoid-nullary-conditions" }, + -- Restrict to bash and zsh + filetypes = { "bash", "zsh" }, + -- Only used if available + condition = utils.is_executable_condition("shellcheck"), + }), + null_ls.builtins.formatting.shfmt.with({ + -- Indent with 4 spaces, simplify the code, indent switch cases, + -- add space after redirection, use bash dialect + extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "bash" }, + -- Restrict to bash and zsh + filetypes = { "bash", "zsh" }, + -- Only used if available + condition = utils.is_executable_condition("shfmt"), + }), +}) + +-- Shell (POSIX) +null_ls.register({ + null_ls.builtins.code_actions.shellcheck.with({ + -- Restrict to POSIX sh + filetypes = { "sh" }, + -- Only used if available + condition = utils.is_executable_condition("shellcheck"), + }), + null_ls.builtins.diagnostics.shellcheck.with({ + -- Show error code in message + diagnostics_format = "[#{c}] #{m}", + -- Require explicit empty string test + extra_args = { "-o", "avoid-nullary-conditions" }, + -- Restrict to POSIX sh + filetypes = { "sh" }, + -- Only used if available + condition = utils.is_executable_condition("shellcheck"), + }), + null_ls.builtins.formatting.shfmt.with({ + -- Indent with 4 spaces, simplify the code, indent switch cases, + -- add space after redirection, use POSIX + extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "posix" }, + -- Restrict to POSIX sh + filetypes = { "sh" }, + -- Only used if available + condition = utils.is_executable_condition("shfmt"), + }), +}) diff --git a/modules/home/vim/plugin/settings/oil.lua b/modules/home/vim/plugin/settings/oil.lua deleted file mode 100644 index 74d5007..0000000 --- a/modules/home/vim/plugin/settings/oil.lua +++ /dev/null @@ -1,36 +0,0 @@ -local oil = require("oil") -local wk = require("which-key") - -local detail = false - -oil.setup({ - -- Don't show icons - columns = {}, - view_options = { - -- Show files and directories that start with "." by default - show_hidden = true, - -- But never '..' - is_always_hidden = function(name, bufnr) - return name == ".." - end, - }, - keymaps = { - ["gd"] = { - desc = "Toggle file detail view", - callback = function() - detail = not detail - if detail then - oil.set_columns({ "icon", "permissions", "size", "mtime" }) - else - oil.set_columns({ "icon" }) - end - end, - }, - }, -}) - -local keys = { - { "-", oil.open, desc = "Open parent directory" }, -} - -wk.add(keys) diff --git a/modules/home/vim/plugin/settings/ssh.lua b/modules/home/vim/plugin/settings/ssh.lua new file mode 100644 index 0000000..992a707 --- /dev/null +++ b/modules/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/modules/home/vim/plugin/settings/telescope.lua b/modules/home/vim/plugin/settings/telescope.lua index 810d51c..4548ec5 100644 --- a/modules/home/vim/plugin/settings/telescope.lua +++ b/modules/home/vim/plugin/settings/telescope.lua @@ -1,6 +1,4 @@ local telescope = require("telescope") -local telescope_builtin = require("telescope.builtin") -local wk = require("which-key") telescope.setup({ defaults = { @@ -23,14 +21,4 @@ telescope.setup({ }) telescope.load_extension("fzf") - -local keys = { - { "f", group = "Fuzzy finder" }, - { "fb", telescope_builtin.buffers, desc = "Open buffers" }, - { "ff", telescope_builtin.git_files, desc = "Git tracked files" }, - { "fF", telescope_builtin.find_files, desc = "Files" }, - { "fg", telescope_builtin.live_grep, desc = "Grep string" }, - { "fG", telescope_builtin.grep_string, desc = "Grep string under cursor" }, -} - -wk.add(keys) +telescope.load_extension("lsp_handlers") diff --git a/modules/home/vim/plugin/settings/tree-sitter.lua b/modules/home/vim/plugin/settings/tree-sitter.lua index d5fff46..5503857 100644 --- a/modules/home/vim/plugin/settings/tree-sitter.lua +++ b/modules/home/vim/plugin/settings/tree-sitter.lua @@ -1,5 +1,4 @@ local ts_config = require("nvim-treesitter.configs") - ts_config.setup({ highlight = { enable = true, @@ -15,16 +14,16 @@ ts_config.setup({ -- Jump to matching text objects lookahead = true, keymaps = { - ["aa"] = { query = "@parameter.outer", desc = "a parameter" }, - ["ia"] = { query = "@parameter.inner", desc = "inner parameter" }, - ["ab"] = { query = "@block.outer", desc = "a block" }, - ["ib"] = { query = "@block.inner", desc = "inner block" }, - ["ac"] = { query = "@class.outer", desc = "a class" }, - ["ic"] = { query = "@class.inner", desc = "inner class" }, - ["af"] = { query = "@function.outer", desc = "a function" }, - ["if"] = { query = "@function.inner", desc = "inner function" }, - ["ak"] = { query = "@comment.outer", desc = "a comment" }, - ["aS"] = { query = "@statement.outer", desc = "a statement" }, + ["aa"] = "@parameter.outer", + ["ia"] = "@parameter.inner", + ["ab"] = "@block.outer", + ["ib"] = "@block.inner", + ["ac"] = "@class.outer", + ["ic"] = "@class.inner", + ["af"] = "@function.outer", + ["if"] = "@function.inner", + ["ak"] = "@comment.outer", + ["aS"] = "@statement.outer", }, }, move = { @@ -32,22 +31,22 @@ ts_config.setup({ -- Add to jump list set_jumps = true, goto_next_start = { - ["]m"] = { query = "@function.outer", desc = "Next method start" }, - ["]S"] = { query = "@statement.outer", desc = "Next statement start" }, - ["]]"] = { query = "@class.outer", desc = "Next class start" }, + ["]m"] = "@function.outer", + ["]S"] = "@statement.outer", + ["]]"] = "@class.outer", }, goto_next_end = { - ["]M"] = { query = "@function.outer", desc = "Next method end" }, - ["]["] = { query = "@class.outer", desc = "Next class end" }, + ["]M"] = "@function.outer", + ["]["] = "@class.outer", }, goto_previous_start = { - ["[m"] = { query = "@function.outer", desc = "Previous method start" }, - ["[S"] = { query = "@statement.outer", desc = "Previous statement start" }, - ["[["] = { query = "@class.outer", desc = "Previous class start" }, + ["[m"] = "@function.outer", + ["[S"] = "@statement.outer", + ["[["] = "@class.outer", }, goto_previous_end = { - ["[M"] = { query = "@function.outer", desc = "Previous method end" }, - ["[]"] = { query = "@class.outer", desc = "Previous class end" }, + ["[M"] = "@function.outer", + ["[]"] = "@class.outer", }, }, }, diff --git a/modules/home/vim/plugin/settings/which-key.lua b/modules/home/vim/plugin/settings/which-key.lua index 3dc260a..2edfd70 100644 --- a/modules/home/vim/plugin/settings/which-key.lua +++ b/modules/home/vim/plugin/settings/which-key.lua @@ -1,33 +1,2 @@ local wk = require("which-key") -wk.setup({ - icons = { - -- I don't like icons - mappings = false, - breadcrumb = "»", - separator = "➜", - group = "+", - ellipsis = "…", - keys = { - Up = " ", - Down = " ", - Left = " ", - Right = " ", - C = "", - M = "", - D = "", - S = "", - CR = "", - Esc = " ", - NL = "", - BS = "", - Space = "", - Tab = " ", - }, - }, -}) - -local keys = { - { "", vim.cmd.nohlsearch, desc = "Clear search highlight" }, -} - -wk.add(keys) +wk.setup() diff --git a/modules/home/vim/plugin/signtoggle.lua b/modules/home/vim/plugin/signtoggle.lua index 3deca34..d6a26e2 100644 --- a/modules/home/vim/plugin/signtoggle.lua +++ b/modules/home/vim/plugin/signtoggle.lua @@ -1,21 +1,20 @@ local signtoggle = vim.api.nvim_create_augroup("signtoggle", { clear = true }) --- Only show sign column for the currently focused buffer, if it has a number column +-- Only show sign column for the currently focused buffer vim.api.nvim_create_autocmd({ "BufEnter", "FocusGained", "WinEnter" }, { pattern = "*", group = signtoggle, - callback = function() - if vim.opt.number:get() then - vim.opt.signcolumn = "yes" - end - end, + command = "setlocal signcolumn=yes", }) vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "WinLeave" }, { pattern = "*", group = signtoggle, - callback = function() - if vim.opt.number:get() then - vim.opt.signcolumn = "no" - end - end, + 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/modules/home/wget/default.nix b/modules/home/wget/default.nix index 1be5397..32c13c0 100644 --- a/modules/home/wget/default.nix +++ b/modules/home/wget/default.nix @@ -20,7 +20,7 @@ in }; xdg.configFile."wgetrc".text = '' - hsts-file = ${config.xdg.stateHome}/wget-hsts + hsts-file = ${config.xdg.dataHome}/wget-hsts ''; }; } diff --git a/modules/home/wm/default.nix b/modules/home/wm/default.nix index ae1e136..449918a 100644 --- a/modules/home/wm/default.nix +++ b/modules/home/wm/default.nix @@ -58,7 +58,7 @@ in service = "some-service-name"; } ]; - description = "list of block configurations, merged with the defaults"; + description = "list of block configurations, merged with the defauls"; }; }; }; diff --git a/modules/home/wm/i3/default.nix b/modules/home/wm/i3/default.nix index 5f22bbe..69246f0 100644 --- a/modules/home/wm/i3/default.nix +++ b/modules/home/wm/i3/default.nix @@ -127,11 +127,9 @@ in { class = "^Blueman-.*$"; } { title = "^htop$"; } { class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; } - { class = "^firefox$"; instance = "Places"; window_role = "Organizer"; } - { class = "^pavucontrol.*$"; } + { class = "^Pavucontrol.*$"; } { class = "^Arandr$"; } - { class = "^\\.blueman-manager-wrapped$"; } - { class = "^\\.arandr-wrapped$"; } + { class = ".?blueman-manager.*$"; } ]; }; @@ -373,7 +371,8 @@ in }; startup = [ - # NOTE: rely on systemd user services instead... + # FIXME + # { commdand; always; notification; } ]; window = { diff --git a/modules/home/wm/screen-lock/default.nix b/modules/home/wm/screen-lock/default.nix index 5e6874e..3b2ead6 100644 --- a/modules/home/wm/screen-lock/default.nix +++ b/modules/home/wm/screen-lock/default.nix @@ -2,7 +2,7 @@ let cfg = config.my.home.wm.screen-lock; - notificationCmd = + notficationCmd = let duration = toString (cfg.notify.delay * 1000); notifyCmd = "${lib.getExe pkgs.libnotify} -u critical -t ${duration}"; @@ -48,7 +48,7 @@ in "-notify" "${toString cfg.notify.delay}" "-notifier" - notificationCmd + notficationCmd ]; }; }; diff --git a/modules/home/xdg/default.nix b/modules/home/xdg/default.nix index 7a0c517..6e49aa1 100644 --- a/modules/home/xdg/default.nix +++ b/modules/home/xdg/default.nix @@ -11,7 +11,7 @@ in enable = true; # File types mime.enable = true; - # File associations + # File associatons mimeApps = { enable = true; }; @@ -30,11 +30,9 @@ in }; # A tidy home is a tidy mind dataFile = { - "tig/.keep".text = ""; # `tig` uses `XDG_DATA_HOME` specifically... - }; - stateFile = { "bash/.keep".text = ""; - "python/.keep".text = ""; + "gdb/.keep".text = ""; + "tig/.keep".text = ""; }; }; @@ -44,19 +42,17 @@ in ANDROID_USER_HOME = "${configHome}/android"; CARGO_HOME = "${dataHome}/cargo"; DOCKER_CONFIG = "${configHome}/docker"; - GRADLE_USER_HOME = "${dataHome}/gradle"; - HISTFILE = "${stateHome}/bash/history"; + GDBHISTFILE = "${dataHome}/gdb/gdb_history"; + HISTFILE = "${dataHome}/bash/history"; INPUTRC = "${configHome}/readline/inputrc"; - PSQL_HISTORY = "${stateHome}/psql_history"; + LESSHISTFILE = "${dataHome}/less/history"; + LESSKEY = "${configHome}/less/lesskey"; + PSQL_HISTORY = "${dataHome}/psql_history"; PYTHONPYCACHEPREFIX = "${cacheHome}/python/"; PYTHONUSERBASE = "${dataHome}/python/"; PYTHON_HISTORY = "${stateHome}/python/history"; - REDISCLI_HISTFILE = "${stateHome}/redis/rediscli_history"; + REDISCLI_HISTFILE = "${dataHome}/redis/rediscli_history"; REPO_CONFIG_DIR = "${configHome}/repo"; XCOMPOSECACHE = "${dataHome}/X11/xcompose"; - _JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${configHome}/java"; }; - - # Some modules *optionally* use `XDG_*_HOME` when told to - config.home.preferXdgDirectories = lib.mkIf cfg.enable true; } diff --git a/modules/home/zsh/default.nix b/modules/home/zsh/default.nix index 9524262..4cadb57 100644 --- a/modules/home/zsh/default.nix +++ b/modules/home/zsh/default.nix @@ -1,174 +1,95 @@ { 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; { enable = my.mkDisableOption "zsh configuration"; launchTmux = mkEnableOption "auto launch tmux at shell start"; - - completionSync = { - enable = mkEnableOption "zsh-completion-sync plugin"; - }; - - notify = { - enable = mkEnableOption "zsh-done notification"; - - exclude = mkOption { - type = with types; listOf str; - default = [ - "bat" - "delta" - "direnv reload" - "fg" - "git (?!push|pull|fetch)" - "home-manager (?!switch|build)" - "htop" - "less" - "man" - "nvim" - "tail -f" - "tmux" - "vim" - ]; - example = [ "command --long-running-option" ]; - description = '' - List of exclusions which should not be create a notification. Accepts - Perl regexes (implicitly anchored with `^\s*`). - ''; - }; - - ssh = { - enable = mkEnableOption "notify through SSH/non-graphical connections"; - - useOsc777 = lib.my.mkDisableOption "use OSC-777 for notifications"; - }; - }; }; - config = lib.mkIf cfg.enable (lib.mkMerge [ - { - home.packages = with pkgs; [ - zsh-completions + config = lib.mkIf cfg.enable { + home.packages = with pkgs; [ + zsh-completions + ]; + + programs.zsh = { + enable = true; + dotDir = "${relativeXdgConfig}/zsh"; # Don't clutter $HOME + enableCompletion = true; + + history = { + size = 500000; + save = 500000; + extended = true; + expireDuplicatesFirst = true; + ignoreSpace = true; + ignoreDups = true; + share = false; + path = "${config.xdg.dataHome}/zsh/zsh_history"; + }; + + plugins = [ + { + name = "fast-syntax-highlighting"; + file = "share/zsh/site-functions/fast-syntax-highlighting.plugin.zsh"; + src = pkgs.zsh-fast-syntax-highlighting; + } + { + name = "agkozak-zsh-prompt"; + file = "share/zsh/site-functions/agkozak-zsh-prompt.plugin.zsh"; + src = pkgs.agkozak-zsh-prompt; + } ]; - programs.zsh = { - enable = true; - dotDir = "${config.xdg.configHome}/zsh"; # Don't clutter $HOME - enableCompletion = true; + # Modal editing is life, but CLI benefits from emacs gymnastics + defaultKeymap = "emacs"; - history = { - size = 500000; - save = 500000; - extended = true; - expireDuplicatesFirst = true; - ignoreSpace = true; - ignoreDups = true; - share = false; - path = "${config.xdg.stateHome}/zsh/zsh_history"; - }; - - plugins = [ - { - name = "fast-syntax-highlighting"; - file = "share/zsh/plugins/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh"; - src = pkgs.zsh-fast-syntax-highlighting; - } - { - name = "agkozak-zsh-prompt"; - file = "share/zsh/site-functions/agkozak-zsh-prompt.plugin.zsh"; - src = pkgs.agkozak-zsh-prompt; - } - ]; - - # Modal editing is life, but CLI benefits from emacs gymnastics - defaultKeymap = "emacs"; - - initContent = lib.mkMerge [ - # Make those happen early to avoid doing double the work - (lib.mkBefore (lib.optionalString cfg.launchTmux '' + # Make those happen early to avoid doing double the work + initExtraFirst = '' + ${ + lib.optionalString cfg.launchTmux '' # Launch tmux unless already inside one if [ -z "$TMUX" ]; then exec tmux new-session fi - '')) - - (lib.mkAfter '' - source ${./completion-styles.zsh} - source ${./extra-mappings.zsh} - source ${./options.zsh} - - # Source local configuration - if [ -f "$ZDOTDIR/zshrc.local" ]; then - source "$ZDOTDIR/zshrc.local" - fi - '') - ]; - - localVariables = { - # I like having the full path - AGKOZAK_PROMPT_DIRTRIM = 0; - # Because I *am* from EPITA - AGKOZAK_PROMPT_CHAR = [ "42sh$" "42sh#" ":" ]; - # Easy on the eyes - AGKOZAK_COLORS_BRANCH_STATUS = "magenta"; - # I don't like moving my eyes - AGKOZAK_LEFT_PROMPT_ONLY = 1; - }; - - # Enable VTE integration - enableVteIntegration = true; - }; - } - - (lib.mkIf cfg.completionSync.enable { - programs.zsh = { - plugins = [ - { - name = "zsh-completion-sync"; - file = "share/zsh-completion-sync/zsh-completion-sync.plugin.zsh"; - src = pkgs.zsh-completion-sync; - } - ]; - }; - }) - - (lib.mkIf cfg.notify.enable { - programs.zsh = { - plugins = [ - { - name = "zsh-done"; - file = "share/zsh/site-functions/done.plugin.zsh"; - src = pkgs.ambroisie.zsh-done; - } - ]; - - # `localVariables` values don't get merged correctly due to their type, - # don't use `mkIf` - localVariables = { - DONE_EXCLUDE = - let - joined = lib.concatMapStringsSep "|" (c: "(${c})") cfg.notify.exclude; - in - ''^\s*(${joined})''; + '' } - # Enable `zsh-done` through SSH, if configured - // lib.optionalAttrs cfg.notify.ssh.enable { - DONE_ALLOW_NONGRAPHICAL = 1; - }; + ''; - # Use OSC-777 to send the notification through SSH - initContent = lib.mkIf cfg.notify.ssh.useOsc777 '' - done_send_notification() { - local exit_status="$1" - local title="$2" - local message="$3" + initExtra = '' + source ${./completion-styles.zsh} + source ${./extra-mappings.zsh} + source ${./options.zsh} - ${lib.getExe pkgs.ambroisie.osc777} "$title" "$message" - } - ''; + # Source local configuration + if [ -f "$ZDOTDIR/zshrc.local" ]; then + source "$ZDOTDIR/zshrc.local" + fi + ''; + + localVariables = { + # I like having the full path + AGKOZAK_PROMPT_DIRTRIM = 0; + # Because I *am* from EPITA + AGKOZAK_PROMPT_CHAR = [ "42sh$" "42sh#" ":" ]; + # Easy on the eyes + AGKOZAK_COLORS_BRANCH_STATUS = "magenta"; + # I don't like moving my eyes + AGKOZAK_LEFT_PROMPT_ONLY = 1; }; - }) - ]); + + # Enable VTE integration + enableVteIntegration = true; + }; + }; } diff --git a/modules/home/zsh/options.zsh b/modules/home/zsh/options.zsh index 7bcad03..32da8d8 100644 --- a/modules/home/zsh/options.zsh +++ b/modules/home/zsh/options.zsh @@ -12,7 +12,7 @@ setopt rc_quotes setopt auto_resume # Show history expansion before running a command setopt hist_verify -# Append commands to history as they are executed +# Append commands to history as they are exectuted setopt inc_append_history_time # Remove useless whitespace from commands setopt hist_reduce_blanks diff --git a/modules/nixos/hardware/bluetooth/default.nix b/modules/nixos/hardware/bluetooth/default.nix index b14ac21..2d840f9 100644 --- a/modules/nixos/hardware/bluetooth/default.nix +++ b/modules/nixos/hardware/bluetooth/default.nix @@ -20,10 +20,28 @@ in # Support for additional bluetooth codecs (lib.mkIf cfg.loadExtraCodecs { - services.pulseaudio = { + hardware.pulseaudio = { extraModules = [ pkgs.pulseaudio-modules-bt ]; package = pkgs.pulseaudioFull; }; + + 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 ]" + } + ''; + }; }) # Support for A2DP audio profile diff --git a/modules/nixos/hardware/graphics/default.nix b/modules/nixos/hardware/graphics/default.nix index 7d8b359..3baac02 100644 --- a/modules/nixos/hardware/graphics/default.nix +++ b/modules/nixos/hardware/graphics/default.nix @@ -26,30 +26,28 @@ in config = lib.mkIf cfg.enable (lib.mkMerge [ { - hardware.graphics = { + hardware.opengl = { enable = true; }; } # AMD GPU (lib.mkIf (cfg.gpuFlavor == "amd") { - hardware.amdgpu = { - initrd.enable = cfg.amd.enableKernelModule; - # Vulkan - amdvlk = lib.mkIf cfg.amd.amdvlk { - enable = true; - support32Bit = { - enable = true; - }; - }; - }; + boot.initrd.kernelModules = lib.mkIf cfg.amd.enableKernelModule [ "amdgpu" ]; - hardware.graphics = { + hardware.opengl = { extraPackages = with pkgs; [ # OpenCL rocmPackages.clr rocmPackages.clr.icd - ]; + ] + ++ lib.optional cfg.amd.amdvlk amdvlk + ; + + extraPackages32 = with pkgs; [ + ] + ++ lib.optional cfg.amd.amdvlk driversi686Linux.amdvlk + ; }; }) @@ -61,7 +59,7 @@ in VDPAU_DRIVER = "va_gl"; }; - hardware.graphics = { + hardware.opengl = { extraPackages = with pkgs; [ # Open CL intel-compute-runtime @@ -71,13 +69,6 @@ in intel-vaapi-driver libvdpau-va-gl ]; - - extraPackages32 = with pkgs.driversi686Linux; [ - # VA API - intel-media-driver - intel-vaapi-driver - libvdpau-va-gl - ]; }; }) ]); diff --git a/modules/nixos/hardware/sound/default.nix b/modules/nixos/hardware/sound/default.nix index cd453de..e8ba7f7 100644 --- a/modules/nixos/hardware/sound/default.nix +++ b/modules/nixos/hardware/sound/default.nix @@ -54,7 +54,10 @@ in # Pulseaudio setup (lib.mkIf cfg.pulse.enable { - services.pulseaudio.enable = true; + # ALSA + sound.enable = true; + + hardware.pulseaudio.enable = true; }) ]); } diff --git a/modules/nixos/hardware/trackball/default.nix b/modules/nixos/hardware/trackball/default.nix index a9b24e3..7a99247 100644 --- a/modules/nixos/hardware/trackball/default.nix +++ b/modules/nixos/hardware/trackball/default.nix @@ -11,7 +11,7 @@ in config = lib.mkIf cfg.enable { services.xserver = { # This section must be *after* the one configured by `libinput` - # for the `ScrollMethod` configuration to not be overridden + # for the `ScrollMethod` configuration to not be overriden inputClassSections = lib.mkAfter [ # MX Ergo '' diff --git a/modules/nixos/profiles/default.nix b/modules/nixos/profiles/default.nix index dbd4be3..43d5a84 100644 --- a/modules/nixos/profiles/default.nix +++ b/modules/nixos/profiles/default.nix @@ -1,4 +1,4 @@ -# Configuration that spans across system and home, or are almagations of modules +# Configuration that spans accross system and home, or are almagations of modules { ... }: { imports = [ diff --git a/modules/nixos/profiles/laptop/default.nix b/modules/nixos/profiles/laptop/default.nix index 68c65b8..20a29d7 100644 --- a/modules/nixos/profiles/laptop/default.nix +++ b/modules/nixos/profiles/laptop/default.nix @@ -9,7 +9,7 @@ in config = lib.mkIf cfg.enable { # Enable touchpad support - services.libinput.enable = true; + services.xserver.libinput.enable = true; # Enable TLP power management my.services.tlp.enable = true; diff --git a/modules/nixos/profiles/wm/default.nix b/modules/nixos/profiles/wm/default.nix index bca4d70..c227328 100644 --- a/modules/nixos/profiles/wm/default.nix +++ b/modules/nixos/profiles/wm/default.nix @@ -24,8 +24,6 @@ in my.home.udiskie.enable = true; # udiskie fails if it can't find this dbus service services.udisks2.enable = true; - # Ensure i3lock can actually unlock the session - security.pam.services.i3lock.enable = true; }) ]; } diff --git a/modules/nixos/profiles/x/default.nix b/modules/nixos/profiles/x/default.nix index 874f36f..ea77939 100644 --- a/modules/nixos/profiles/x/default.nix +++ b/modules/nixos/profiles/x/default.nix @@ -13,7 +13,7 @@ in # Nice wallpaper services.xserver.displayManager.lightdm.background = let - wallpapers = "${pkgs.kdePackages.plasma-workspace-wallpapers}/share/wallpapers"; + wallpapers = "${pkgs.plasma5Packages.plasma-workspace-wallpapers}/share/wallpapers"; in "${wallpapers}/summer_1am/contents/images/2560x1600.jpg"; diff --git a/modules/nixos/services/aria/default.nix b/modules/nixos/services/aria/default.nix index acbf0b7..2d1b3e2 100644 --- a/modules/nixos/services/aria/default.nix +++ b/modules/nixos/services/aria/default.nix @@ -65,7 +65,9 @@ in aria-rpc = { port = cfg.rpcPort; # Proxy websockets for RPC - websocketsLocations = [ "/" ]; + extraConfig = { + locations."/".proxyWebsockets = true; + }; }; }; diff --git a/modules/nixos/services/audiobookshelf/default.nix b/modules/nixos/services/audiobookshelf/default.nix deleted file mode 100644 index 04ec8b9..0000000 --- a/modules/nixos/services/audiobookshelf/default.nix +++ /dev/null @@ -1,53 +0,0 @@ -# Audiobook and podcast library -{ config, lib, ... }: -let - cfg = config.my.services.audiobookshelf; -in -{ - options.my.services.audiobookshelf = with lib; { - enable = mkEnableOption "Audiobookshelf, a self-hosted podcast manager"; - - port = mkOption { - type = types.port; - default = 8000; - example = 4242; - description = "The port on which Audiobookshelf will listen for incoming HTTP traffic."; - }; - }; - - config = lib.mkIf cfg.enable { - services.audiobookshelf = { - enable = true; - inherit (cfg) port; - - group = "media"; - }; - - # Set-up media group - users.groups.media = { }; - - my.services.nginx.virtualHosts = { - audiobookshelf = { - inherit (cfg) port; - # Proxy websockets for RPC - websocketsLocations = [ "/" ]; - }; - }; - - services.fail2ban.jails = { - audiobookshelf = '' - enabled = true - filter = audiobookshelf - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/audiobookshelf.conf".text = '' - [Definition] - failregex = ^.*ERROR: \[Auth\] Failed login attempt for username ".*" from ip - journalmatch = _SYSTEMD_UNIT=audiobookshelf.service - ''; - }; - }; -} diff --git a/modules/nixos/services/backup/default.nix b/modules/nixos/services/backup/default.nix index 8aeeae1..ff0fc7f 100644 --- a/modules/nixos/services/backup/default.nix +++ b/modules/nixos/services/backup/default.nix @@ -89,16 +89,6 @@ in }; config = lib.mkIf cfg.enable { - # Essential files which should always be backed up - my.services.backup.paths = lib.flatten [ - # Should be unique to a given host, used by some software (e.g: ZFS) - "/etc/machine-id" - # Contains the UID/GID map, and other useful state - "/var/lib/nixos" - # SSH host keys (and public keys for convenience) - (builtins.map (key: [ key.path "${key.path}.pub" ]) config.services.openssh.hostKeys) - ]; - services.restic.backups.backblaze = { # Take care of included and excluded files paths = cfg.paths; diff --git a/modules/nixos/services/blog/default.nix b/modules/nixos/services/blog/default.nix index e4d2d42..3e68df2 100644 --- a/modules/nixos/services/blog/default.nix +++ b/modules/nixos/services/blog/default.nix @@ -35,7 +35,7 @@ in useACMEHost = domain; default = true; - locations."/".return = "302 https://${domain}$request_uri"; + locations."/".return = "302 https://belanyi.fr$request_uri"; }; }; diff --git a/modules/nixos/services/default.nix b/modules/nixos/services/default.nix index e03eca1..67504da 100644 --- a/modules/nixos/services/default.nix +++ b/modules/nixos/services/default.nix @@ -4,22 +4,18 @@ imports = [ ./adblock ./aria - ./audiobookshelf ./backup ./blog ./calibre-web ./drone ./fail2ban ./flood - ./forgejo ./gitea ./grocy - ./homebox + ./indexers ./jellyfin - ./komga ./lohr ./matrix - ./mealie ./miniflux ./monitoring ./navidrome @@ -27,7 +23,7 @@ ./nginx ./nix-cache ./paperless - ./pdf-edit + ./pirate ./podgrab ./postgresql ./postgresql-backup @@ -35,10 +31,8 @@ ./quassel ./rss-bridge ./sabnzbd - ./servarr ./ssh-server ./tandoor-recipes - ./thelounge ./tlp ./transmission ./vikunja diff --git a/modules/nixos/services/drone/server/default.nix b/modules/nixos/services/drone/server/default.nix index d6148f4..a3a1e49 100644 --- a/modules/nixos/services/drone/server/default.nix +++ b/modules/nixos/services/drone/server/default.nix @@ -6,8 +6,8 @@ in config = lib.mkIf cfg.enable { systemd.services.drone-server = { wantedBy = [ "multi-user.target" ]; - after = [ "postgresql.target" ]; - requires = [ "postgresql.target" ]; + after = [ "postgresql.service" ]; + requires = [ "postgresql.service" ]; serviceConfig = { EnvironmentFile = [ cfg.secretFile diff --git a/modules/nixos/services/flood/default.nix b/modules/nixos/services/flood/default.nix index f3fe90b..155e73d 100644 --- a/modules/nixos/services/flood/default.nix +++ b/modules/nixos/services/flood/default.nix @@ -1,5 +1,5 @@ # A nice UI for various torrent clients -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.my.services.flood; in @@ -13,13 +13,31 @@ in example = 3000; description = "Internal port for Flood UI"; }; + + stateDir = mkOption { + type = types.str; + default = "flood"; + example = "floodUI"; + description = "Directory under `/var/run` for storing Flood's files"; + }; }; config = lib.mkIf cfg.enable { - services.flood = { - enable = true; + systemd.services.flood = { + description = "Flood torrent UI"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; - inherit (cfg) port; + serviceConfig = { + ExecStart = lib.concatStringsSep " " [ + (lib.getExe pkgs.flood) + "--port ${builtins.toString cfg.port}" + "--rundir /var/lib/${cfg.stateDir}" + ]; + DynamicUser = true; + StateDirectory = cfg.stateDir; + ReadWritePaths = ""; + }; }; my.services.nginx.virtualHosts = { @@ -27,7 +45,5 @@ in inherit (cfg) port; }; }; - - # NOTE: unfortunately flood does not log connection failures for fail2ban }; } diff --git a/modules/nixos/services/forgejo/default.nix b/modules/nixos/services/forgejo/default.nix deleted file mode 100644 index 511724b..0000000 --- a/modules/nixos/services/forgejo/default.nix +++ /dev/null @@ -1,166 +0,0 @@ -# A low-resource, full-featured git forge. -{ config, lib, ... }: -let - cfg = config.my.services.forgejo; -in -{ - options.my.services.forgejo = with lib; { - enable = mkEnableOption "Forgejo"; - port = mkOption { - type = types.port; - default = 3042; - example = 8080; - description = "Internal port"; - }; - mail = { - enable = mkEnableOption { - description = "mailer configuration"; - }; - host = mkOption { - type = types.str; - example = "smtp.example.com"; - description = "Host for the mail account"; - }; - port = mkOption { - type = types.port; - default = 465; - example = 587; - description = "Port for the mail account"; - }; - user = mkOption { - type = types.str; - example = "forgejo@example.com"; - description = "User for the mail account"; - }; - passwordFile = mkOption { - type = types.str; - example = "/run/secrets/forgejo-mail-password.txt"; - description = "Password for the mail account"; - }; - protocol = mkOption { - type = types.str; - default = "smtps"; - example = "smtp"; - description = "Protocol for connection"; - }; - }; - }; - - config = lib.mkIf cfg.enable { - assertions = [ - { - assertion = cfg.enable -> !config.my.services.gitea.enable; - message = '' - `config.my.services.forgejo` is incompatible with - `config.my.services.gitea`. - ''; - } - ]; - - services.forgejo = - let - inherit (config.networking) domain; - forgejoDomain = "git.${domain}"; - in - { - enable = true; - - user = "git"; - group = "git"; - - lfs.enable = true; - - useWizard = false; - - database = { - type = "postgres"; # Automatic setup - user = "git"; # User needs to be the same as forgejo user - name = "git"; # Name must be the same as user for `ensureDBOwnership` - }; - - # NixOS module uses `forgejo dump` to backup repositories and the database, - # but it produces a single .zip file that's not very backup friendly. - # I configure my backup system manually below. - dump.enable = false; - - secrets = { - mailer = lib.mkIf cfg.mail.enable { - PASSWD = cfg.mail.passwordFile; - }; - }; - - settings = { - DEFAULT = { - APP_NAME = "Ambroisie's forge"; - }; - - server = { - HTTP_PORT = cfg.port; - DOMAIN = forgejoDomain; - ROOT_URL = "https://${forgejoDomain}"; - }; - - mailer = lib.mkIf cfg.mail.enable { - ENABLED = true; - SMTP_ADDR = cfg.mail.host; - SMTP_PORT = cfg.mail.port; - FROM = "Forgejo <${cfg.mail.user}>"; - USER = cfg.mail.user; - PROTOCOL = cfg.mail.protocol; - }; - - service = { - DISABLE_REGISTRATION = true; - }; - - session = { - # only send cookies via HTTPS - COOKIE_SECURE = true; - }; - }; - }; - - users.users.git = { - description = "Forgejo Service"; - home = config.services.forgejo.stateDir; - useDefaultShell = true; - group = "git"; - isSystemUser = true; - }; - users.groups.git = { }; - - my.services.nginx.virtualHosts = { - # Proxy to Forgejo - git = { - inherit (cfg) port; - }; - # Redirect `forgejo.` to actual forge subdomain - forgejo = { - redirect = config.services.forgejo.settings.server.ROOT_URL; - }; - }; - - my.services.backup = { - paths = [ - config.services.forgejo.lfs.contentDir - config.services.forgejo.repositoryRoot - ]; - }; - - services.fail2ban.jails = { - forgejo = '' - enabled = true - filter = forgejo - action = iptables-allports - ''; - }; - - environment.etc = { - "fail2ban/filter.d/forgejo.conf".text = '' - [Definition] - failregex = ^.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from $ - journalmatch = _SYSTEMD_UNIT=forgejo.service - ''; - }; - }; -} diff --git a/modules/nixos/services/gitea/default.nix b/modules/nixos/services/gitea/default.nix index 95bdf42..4a8a3bb 100644 --- a/modules/nixos/services/gitea/default.nix +++ b/modules/nixos/services/gitea/default.nix @@ -1,4 +1,4 @@ -# A low-resource, full-featured git forge. +# A low-ressource, full-featured git forge. { config, lib, ... }: let cfg = config.my.services.gitea; @@ -18,15 +18,9 @@ in }; host = mkOption { type = types.str; - example = "smtp.example.com"; + example = "smtp.example.com:465"; description = "Host for the mail account"; }; - port = mkOption { - type = types.port; - default = 465; - example = 587; - description = "Port for the mail account"; - }; user = mkOption { type = types.str; example = "gitea@example.com"; @@ -37,11 +31,17 @@ in example = "/run/secrets/gitea-mail-password.txt"; description = "Password for the mail account"; }; - protocol = mkOption { + type = mkOption { type = types.str; - default = "smtps"; + default = "smtp"; example = "smtp"; - description = "Protocol for connection"; + description = "Password for the mail account"; + }; + tls = mkOption { + type = types.bool; + default = true; + example = false; + description = "Use TLS for connection"; }; }; }; @@ -58,8 +58,6 @@ in appName = "Ambroisie's forge"; user = "git"; - group = "git"; - lfs.enable = true; useWizard = false; @@ -86,11 +84,11 @@ in mailer = lib.mkIf cfg.mail.enable { ENABLED = true; - SMTP_ADDR = cfg.mail.host; - SMTP_PORT = cfg.mail.port; - FROM = "Gitea <${cfg.mail.user}>"; + HOST = cfg.mail.host; + FROM = cfg.mail.user; USER = cfg.mail.user; - PROTOCOL = cfg.mail.protocol; + MAILER_TYPE = cfg.mail.type; + IS_TLS_ENABLED = cfg.mail.tls; }; service = { @@ -109,6 +107,11 @@ in home = config.services.gitea.stateDir; useDefaultShell = true; group = "git"; + + # The service for gitea seems to hardcode the group as + # gitea, so, uh, just in case? + extraGroups = [ "gitea" ]; + isSystemUser = true; }; users.groups.git = { }; diff --git a/modules/nixos/services/grocy/default.nix b/modules/nixos/services/grocy/default.nix index 9045b03..87927d6 100644 --- a/modules/nixos/services/grocy/default.nix +++ b/modules/nixos/services/grocy/default.nix @@ -36,7 +36,5 @@ in forceSSL = true; useACMEHost = config.networking.domain; }; - - # NOTE: unfortunately grocy does not log connection failures for fail2ban }; } diff --git a/modules/nixos/services/homebox/default.nix b/modules/nixos/services/homebox/default.nix deleted file mode 100644 index 524a6d7..0000000 --- a/modules/nixos/services/homebox/default.nix +++ /dev/null @@ -1,48 +0,0 @@ -# Home inventory made easy -{ config, lib, ... }: -let - cfg = config.my.services.homebox; -in -{ - options.my.services.homebox = with lib; { - enable = mkEnableOption "Homebox home inventory"; - - port = mkOption { - type = types.port; - default = 7745; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.homebox = { - enable = true; - - # Automatic PostgreSQL provisioning - database = { - createLocally = true; - }; - - settings = { - # FIXME: mailer? - HBOX_WEB_PORT = toString cfg.port; - }; - }; - - my.services.nginx.virtualHosts = { - homebox = { - inherit (cfg) port; - websocketsLocations = [ "/api" ]; - }; - }; - - my.services.backup = { - paths = [ - (lib.removePrefix "file://" config.services.homebox.settings.HBOX_STORAGE_CONN_STRING) - ]; - }; - - # NOTE: unfortunately homebox does not log connection failures for fail2ban - }; -} diff --git a/modules/nixos/services/indexers/default.nix b/modules/nixos/services/indexers/default.nix new file mode 100644 index 0000000..8a42345 --- /dev/null +++ b/modules/nixos/services/indexers/default.nix @@ -0,0 +1,78 @@ +# Torrent and usenet meta-indexers +{ config, lib, ... }: +let + cfg = config.my.services.indexers; + + jackettPort = 9117; + nzbhydraPort = 5076; + prowlarrPort = 9696; +in +{ + options.my.services.indexers = with lib; { + jackett.enable = mkEnableOption "Jackett torrent meta-indexer"; + nzbhydra.enable = mkEnableOption "NZBHydra2 usenet meta-indexer"; + prowlarr.enable = mkEnableOption "Prowlarr torrent & usenet meta-indexer"; + }; + + config = lib.mkMerge [ + (lib.mkIf cfg.jackett.enable { + services.jackett = { + enable = true; + }; + + # Jackett wants to eat *all* my RAM if left to its own devices + systemd.services.jackett = { + serviceConfig = { + MemoryHigh = "15%"; + MemoryMax = "25%"; + }; + }; + + my.services.nginx.virtualHosts = { + jackett = { + port = jackettPort; + }; + }; + }) + + (lib.mkIf cfg.nzbhydra.enable { + services.nzbhydra2 = { + enable = true; + }; + + my.services.nginx.virtualHosts = { + nzbhydra = { + port = nzbhydraPort; + }; + }; + }) + + (lib.mkIf cfg.prowlarr.enable { + services.prowlarr = { + enable = true; + }; + + my.services.nginx.virtualHosts = { + prowlarr = { + port = prowlarrPort; + }; + }; + + services.fail2ban.jails = { + prowlarr = '' + enabled = true + filter = prowlarr + action = iptables-allports + ''; + }; + + environment.etc = { + "fail2ban/filter.d/prowlarr.conf".text = '' + [Definition] + failregex = ^.*\|Warn\|Auth\|Auth-Failure ip username .*$ + journalmatch = _SYSTEMD_UNIT=prowlarr.service + ''; + }; + }) + ]; +} diff --git a/modules/nixos/services/jellyfin/default.nix b/modules/nixos/services/jellyfin/default.nix index 6edeb67..f5aaa99 100644 --- a/modules/nixos/services/jellyfin/default.nix +++ b/modules/nixos/services/jellyfin/default.nix @@ -27,31 +27,19 @@ in my.services.nginx.virtualHosts = { jellyfin = { port = 8096; - websocketsLocations = [ "/socket" ]; extraConfig = { locations."/" = { extraConfig = '' proxy_buffering off; ''; }; + # Too bad for the repetition... + locations."/socket" = { + proxyPass = "http://127.0.0.1:8096/"; + proxyWebsockets = true; + }; }; }; }; - - services.fail2ban.jails = { - jellyfin = '' - enabled = true - filter = jellyfin - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/jellyfin.conf".text = '' - [Definition] - failregex = ^.*Authentication request for .* has been denied \(IP: "?"?\)\. - journalmatch = _SYSTEMD_UNIT=jellyfin.service - ''; - }; }; } diff --git a/modules/nixos/services/komga/default.nix b/modules/nixos/services/komga/default.nix deleted file mode 100644 index 9af3cd1..0000000 --- a/modules/nixos/services/komga/default.nix +++ /dev/null @@ -1,55 +0,0 @@ -# A Comics/Manga media server -{ config, lib, ... }: -let - cfg = config.my.services.komga; -in -{ - options.my.services.komga = with lib; { - enable = mkEnableOption "Komga comics server"; - - port = mkOption { - type = types.port; - default = 4584; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.komga = { - enable = true; - - group = "media"; - - settings = { - server.port = cfg.port; - logging.level.org.gotson.komga = "DEBUG"; # Needed for fail2ban - }; - }; - - # Set-up media group - users.groups.media = { }; - - my.services.nginx.virtualHosts = { - komga = { - inherit (cfg) port; - }; - }; - - services.fail2ban.jails = { - komga = '' - enabled = true - filter = komga - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/komga.conf".text = '' - [Definition] - failregex = ^.* ip=,.*Bad credentials.*$ - journalmatch = _SYSTEMD_UNIT=komga.service - ''; - }; - }; -} diff --git a/modules/nixos/services/lohr/default.nix b/modules/nixos/services/lohr/default.nix index 21ed93b..dd4eea8 100644 --- a/modules/nixos/services/lohr/default.nix +++ b/modules/nixos/services/lohr/default.nix @@ -59,6 +59,21 @@ in "LOHR_HOME=${lohrHome}" "LOHR_CONFIG=" ]; + ExecStartPre = lib.mkIf (cfg.sshKeyFile != null) ''+${ + pkgs.writeScript "copy-ssh-key" '' + #!${pkgs.bash}/bin/bash + # Ensure the key is not there + mkdir -p '${lohrHome}/.ssh' + rm -f '${lohrHome}/.ssh/id_ed25519' + + # Move the key into place + cp ${cfg.sshKeyFile} '${lohrHome}/.ssh/id_ed25519' + + # Fix permissions + chown -R lohr:lohr '${lohrHome}/.ssh' + chmod -R 0700 '${lohrHome}/.ssh' + '' + }''; ExecStart = let configFile = settingsFormat.generate "lohr-config.yaml" cfg.setting; @@ -88,24 +103,5 @@ in inherit (cfg) port; }; }; - - # SSH key provisioning - systemd.tmpfiles.settings."10-lohr" = lib.mkIf (cfg.sshKeyFile != null) { - "${lohrHome}/.ssh" = { - d = { - user = "lohr"; - group = "lohr"; - mode = "0700"; - }; - }; - "${lohrHome}/.ssh/id_ed25519" = { - "L+" = { - user = "lohr"; - group = "lohr"; - mode = "0700"; - argument = cfg.sshKeyFile; - }; - }; - }; }; } diff --git a/modules/nixos/services/matrix/bridges.nix b/modules/nixos/services/matrix/bridges.nix deleted file mode 100644 index 70f4118..0000000 --- a/modules/nixos/services/matrix/bridges.nix +++ /dev/null @@ -1,143 +0,0 @@ -# Matrix bridges for some services I use -{ config, lib, ... }: -let - cfg = config.my.services.matrix.bridges; - synapseCfg = config.services.matrix-synapse; - - domain = config.networking.domain; - serverName = synapseCfg.settings.server_name; - - mkBridgeOption = n: lib.mkEnableOption "${n} bridge" // { default = cfg.enable; }; - mkPortOption = n: default: lib.mkOption { - type = lib.types.port; - inherit default; - example = 8080; - description = "${n} bridge port"; - }; - mkEnvironmentFileOption = n: lib.mkOption { - type = lib.types.str; - example = "/run/secret/matrix/${lib.toLower n}-bridge-secrets.env"; - description = '' - Path to a file which should contain the secret values for ${n} bridge. - - Using through the following format: - - ``` - MATRIX_APPSERVICE_AS_TOKEN= - MATRIX_APPSERVICE_HS_TOKEN= - ``` - - Each bridge should use a different set of secrets, as they each register - their own independent double-puppetting appservice. - ''; - }; -in -{ - options.my.services.matrix.bridges = with lib; { - enable = mkEnableOption "bridges configuration"; - - admin = mkOption { - type = types.str; - default = "ambroisie"; - example = "admin"; - description = "Local username for the admin"; - }; - - facebook = { - enable = mkBridgeOption "Facebook"; - - port = mkPortOption "Facebook" 29321; - - environmentFile = mkEnvironmentFileOption "Facebook"; - }; - }; - - config = lib.mkMerge [ - (lib.mkIf cfg.facebook.enable { - services.mautrix-meta.instances.facebook = { - enable = true; - # Automatically register the bridge with synapse - registerToSynapse = true; - - # Provide `AS_TOKEN`, `HS_TOKEN` - inherit (cfg.facebook) environmentFile; - - settings = { - homeserver = { - domain = serverName; - address = "http://localhost:${toString config.my.services.matrix.port}"; - }; - - appservice = { - hostname = "localhost"; - inherit (cfg.facebook) port; - address = "http://localhost:${toString cfg.facebook.port}"; - public_address = "https://facebook-bridge.${domain}"; - - as_token = "$MATRIX_APPSERVICE_AS_TOKEN"; - hs_token = "$MATRIX_APPSERVICE_HS_TOKEN"; - - bot = { - username = "fbbot"; - }; - }; - - backfill = { - enabled = true; - }; - - bridge = { - delivery_receipts = true; - permissions = { - "*" = "relay"; - ${serverName} = "user"; - "@${cfg.admin}:${serverName}" = "admin"; - }; - }; - - database = { - type = "postgres"; - uri = "postgres:///mautrix-meta-facebook?host=/var/run/postgresql/"; - }; - - double_puppet = { - secrets = { - ${serverName} = "as_token:$MATRIX_APPSERVICE_AS_TOKEN"; - }; - }; - - network = { - # Don't be picky on Facebook/Messenger - allow_messenger_com_on_fb = true; - displayname_template = ''{{or .DisplayName .Username "Unknown user"}} (FB)''; - }; - - provisioning = { - shared_secret = "disable"; - }; - }; - }; - - services.postgresql = { - enable = true; - ensureDatabases = [ "mautrix-meta-facebook" ]; - ensureUsers = [{ - name = "mautrix-meta-facebook"; - ensureDBOwnership = true; - }]; - }; - - systemd.services.mautrix-meta-facebook = { - wants = [ "postgres.service" ]; - after = [ "postgres.service" ]; - }; - - my.services.nginx.virtualHosts = { - # Proxy to the bridge - "facebook-bridge" = { - inherit (cfg.facebook) port; - }; - }; - }) - ]; -} diff --git a/modules/nixos/services/matrix/default.nix b/modules/nixos/services/matrix/default.nix index 97dec2e..b958f76 100644 --- a/modules/nixos/services/matrix/default.nix +++ b/modules/nixos/services/matrix/default.nix @@ -1,49 +1,24 @@ -# Matrix homeserver setup. +# Matrix homeserver setup, using different endpoints for federation and client +# traffic. The main trick for this is defining two nginx servers endpoints for +# matrix.domain.com, each listening on different ports. +# +# Configuration shamelessly stolen from [1] +# +# [1]: https://github.com/alarsyo/nixos-config/blob/main/services/matrix.nix { config, lib, pkgs, ... }: let cfg = config.my.services.matrix; - adminPkg = pkgs.synapse-admin-etkecc; - + federationPort = { public = 8448; private = 11338; }; + clientPort = { public = 443; private = 11339; }; domain = config.networking.domain; matrixDomain = "matrix.${domain}"; - - serverConfig = { - "m.server" = "${matrixDomain}:443"; - }; - clientConfig = { - "m.homeserver" = { - "base_url" = "https://${matrixDomain}"; - "server_name" = domain; - }; - "m.identity_server" = { - "base_url" = "https://vector.im"; - }; - }; - - # ACAO required to allow element-web on any URL to request this json file - mkWellKnown = data: '' - default_type application/json; - add_header Access-Control-Allow-Origin *; - return 200 '${builtins.toJSON data}'; - ''; in { - imports = [ - ./bridges.nix - ]; - options.my.services.matrix = with lib; { enable = mkEnableOption "Matrix Synapse"; - port = mkOption { - type = types.port; - default = 8448; - example = 8008; - description = "Internal port for listeners"; - }; - secretFile = mkOption { type = with types; nullOr str; default = null; @@ -51,6 +26,21 @@ in description = "Shared secret to register users"; }; + slidingSync = { + port = mkOption { + type = types.port; + default = 8009; + example = 8084; + description = "Port used by sliding sync server"; + }; + + secretFile = mkOption { + type = types.str; + example = "/var/lib/matrix/sliding-sync-secret-file.env"; + description = "Secret file which contains SYNCV3_SECRET definition"; + }; + }; + mailConfigFile = mkOption { type = types.str; example = "/var/lib/matrix/email-config.yaml"; @@ -83,22 +73,22 @@ in enable_registration = false; listeners = [ + # Federation { - inherit (cfg) port; bind_addresses = [ "::1" ]; - type = "http"; - tls = false; + port = federationPort.private; + tls = false; # Terminated by nginx. x_forwarded = true; - resources = [ - { - names = [ "client" ]; - compress = true; - } - { - names = [ "federation" ]; - compress = false; - } - ]; + resources = [{ names = [ "federation" ]; compress = false; }]; + } + + # Client + { + bind_addresses = [ "::1" ]; + port = clientPort.private; + tls = false; # Terminated by nginx. + x_forwarded = true; + resources = [{ names = [ "client" ]; compress = false; }]; } ]; @@ -116,17 +106,38 @@ in ] ++ lib.optional (cfg.secretFile != null) cfg.secretFile; }; + services.matrix-sliding-sync = { + enable = true; + + settings = { + SYNCV3_SERVER = "https://${matrixDomain}"; + SYNCV3_BINDADDR = "127.0.0.1:${toString cfg.slidingSync.port}"; + }; + + environmentFile = cfg.slidingSync.secretFile; + }; + my.services.nginx.virtualHosts = { # Element Web app deployment chat = { root = pkgs.element-web.override { conf = { - default_server_config = clientConfig; - show_labs_settings = true; - default_country_code = "FR"; # cocorico - room_directory = { + default_server_config = { + "m.homeserver" = { + "base_url" = "https://${matrixDomain}"; + "server_name" = domain; + }; + "m.identity_server" = { + "base_url" = "https://vector.im"; + }; + "org.matrix.msc3575.proxy" = { + "url" = "https://matrix-sync.${domain}"; + }; + }; + showLabsSettings = true; + defaultCountryCode = "FR"; # cocorico + roomDirectory = { "servers" = [ - domain "matrix.org" "mozilla.org" ]; @@ -134,54 +145,109 @@ in }; }; }; - matrix = { - # Somewhat unused, but necessary for port collision detection - inherit (cfg) port; - - extraConfig = { - locations = { - # Or do a redirect instead of the 404, or whatever is appropriate - # for you. But do not put a Matrix Web client here! See the - # Element web section above. - "/".return = "404"; - - "/_matrix".proxyPass = "http://[::1]:${toString cfg.port}"; - "/_synapse".proxyPass = "http://[::1]:${toString cfg.port}"; - - "= /admin".return = "307 /admin/"; - "/admin/" = { - alias = "${adminPkg}/"; - priority = 500; - tryFiles = "$uri $uri/ /index.html"; - }; - "~ ^/admin/.*\\.(?:css|js|jpg|jpeg|gif|png|svg|ico|woff|woff2|ttf|eot|webp)$" = { - priority = 400; - root = adminPkg; - extraConfig = '' - rewrite ^/admin/(.*)$ /$1 break; - expires 30d; - more_set_headers "Cache-Control: public"; - ''; - }; - }; - }; + # Dummy VHosts for port collision detection + matrix-federation = { + port = federationPort.private; + }; + matrix-client = { + port = clientPort.private; + }; + # Sliding sync + matrix-sync = { + inherit (cfg.slidingSync) port; }; }; - # Setup well-known locations + # Those are too complicated to use my wrapper... services.nginx.virtualHosts = { + ${matrixDomain} = { + onlySSL = true; + useACMEHost = domain; + + locations = + let + proxyToClientPort = { + proxyPass = "http://[::1]:${toString clientPort.private}"; + }; + in + { + # Or do a redirect instead of the 404, or whatever is appropriate + # for you. But do not put a Matrix Web client here! See the + # Element web section below. + "/".return = "404"; + + "/_matrix" = proxyToClientPort; + "/_synapse/client" = proxyToClientPort; + + # Sliding sync + "~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = { + proxyPass = "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}"; + }; + }; + + listen = [ + { addr = "0.0.0.0"; port = clientPort.public; ssl = true; } + { addr = "[::]"; port = clientPort.public; ssl = true; } + ]; + + }; + + # same as above, but listening on the federation port + "${matrixDomain}_federation" = { + onlySSL = true; + serverName = matrixDomain; + useACMEHost = domain; + + locations."/".return = "404"; + + locations."/_matrix" = { + proxyPass = "http://[::1]:${toString federationPort.private}"; + }; + + listen = [ + { addr = "0.0.0.0"; port = federationPort.public; ssl = true; } + { addr = "[::]"; port = federationPort.public; ssl = true; } + ]; + }; + "${domain}" = { forceSSL = true; useACMEHost = domain; - locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; - locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; + locations."= /.well-known/matrix/server".extraConfig = + let + server = { "m.server" = "${matrixDomain}:${toString federationPort.public}"; }; + in + '' + add_header Content-Type application/json; + return 200 '${builtins.toJSON server}'; + ''; + + locations."= /.well-known/matrix/client".extraConfig = + let + client = { + "m.homeserver" = { "base_url" = "https://${matrixDomain}"; }; + "m.identity_server" = { "base_url" = "https://vector.im"; }; + "org.matrix.msc3575.proxy" = { "url" = "https://matrix-sync.${domain}"; }; + }; + # ACAO required to allow element-web on any URL to request this json file + in + '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + return 200 '${builtins.toJSON client}'; + ''; }; }; # For administration tools. environment.systemPackages = [ pkgs.matrix-synapse ]; + networking.firewall.allowedTCPPorts = [ + clientPort.public + federationPort.public + ]; + my.services.backup = { paths = [ config.services.matrix-synapse.dataDir diff --git a/modules/nixos/services/mealie/default.nix b/modules/nixos/services/mealie/default.nix deleted file mode 100644 index f3774e1..0000000 --- a/modules/nixos/services/mealie/default.nix +++ /dev/null @@ -1,79 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.my.services.mealie; -in -{ - options.my.services.mealie = with lib; { - enable = mkEnableOption "Mealie service"; - - port = mkOption { - type = types.port; - default = 4537; - example = 8080; - description = "Internal port for webui"; - }; - - credentialsFile = mkOption { - type = types.str; - example = "/var/lib/mealie/credentials.env"; - description = '' - Configuration file for secrets. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - services.mealie = { - enable = true; - inherit (cfg) port credentialsFile; - - settings = { - # Basic settings - BASE_URL = "https://mealie.${config.networking.domain}"; - TZ = config.time.timeZone; - ALLOw_SIGNUP = "false"; - TOKEN_TIME = 24 * 180; # 180 days - }; - - # Automatic PostgreSQL provisioning - database = { - createLocally = true; - }; - }; - - my.services.nginx.virtualHosts = { - mealie = { - inherit (cfg) port; - - extraConfig = { - # Allow bulk upload of recipes for import/export - locations."/".extraConfig = '' - client_max_body_size 0; - ''; - }; - }; - }; - - my.services.backup = { - paths = [ - "/var/lib/mealie" - ]; - }; - - services.fail2ban.jails = { - mealie = '' - enabled = true - filter = mealie - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/mealie.conf".text = '' - [Definition] - failregex = ^.*ERROR.*Incorrect username or password from - journalmatch = _SYSTEMD_UNIT=mealie.service - ''; - }; - }; -} diff --git a/modules/nixos/services/miniflux/default.nix b/modules/nixos/services/miniflux/default.nix index 400ae00..5104c8b 100644 --- a/modules/nixos/services/miniflux/default.nix +++ b/modules/nixos/services/miniflux/default.nix @@ -48,21 +48,5 @@ in inherit (cfg) port; }; }; - - services.fail2ban.jails = { - miniflux = '' - enabled = true - filter = miniflux - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/miniflux.conf".text = '' - [Definition] - failregex = ^.*msg="[^"]*(Incorrect|Invalid) username or password[^"]*".*client_ip= - journalmatch = _SYSTEMD_UNIT=miniflux.service - ''; - }; }; } diff --git a/modules/nixos/services/navidrome/default.nix b/modules/nixos/services/navidrome/default.nix index c513b91..944a97a 100644 --- a/modules/nixos/services/navidrome/default.nix +++ b/modules/nixos/services/navidrome/default.nix @@ -52,21 +52,5 @@ in inherit (cfg) port; }; }; - - services.fail2ban.jails = { - navidrome = '' - enabled = true - filter = navidrome - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/navidrome.conf".text = '' - [Definition] - failregex = ^.*msg="Unsuccessful login".*X-Real-Ip:\[\] - journalmatch = _SYSTEMD_UNIT=navidrome.service - ''; - }; }; } diff --git a/modules/nixos/services/nextcloud/collabora.nix b/modules/nixos/services/nextcloud/collabora.nix deleted file mode 100644 index 408b232..0000000 --- a/modules/nixos/services/nextcloud/collabora.nix +++ /dev/null @@ -1,56 +0,0 @@ -# Document editor with Nextcloud -{ config, lib, ... }: -let - cfg = config.my.services.nextcloud.collabora; -in -{ - options.my.services.nextcloud.collabora = with lib; { - enable = mkEnableOption "Collabora integration"; - - port = mkOption { - type = types.port; - default = 9980; - example = 8080; - description = "Internal port for API"; - }; - }; - - config = lib.mkIf cfg.enable { - services.nextcloud = { - extraApps = { - inherit (config.services.nextcloud.package.packages.apps) richdocuments; - }; - }; - - services.collabora-online = { - enable = true; - inherit (cfg) port; - - aliasGroups = [ - { - host = "https://collabora.${config.networking.domain}"; - # Allow using from nextcloud - aliases = [ "https://${config.services.nextcloud.hostName}" ]; - } - ]; - - settings = { - # Rely on reverse proxy for SSL - ssl = { - enable = false; - termination = true; - }; - }; - }; - - my.services.nginx.virtualHosts = { - collabora = { - inherit (cfg) port; - websocketsLocations = [ - "~ ^/cool/(.*)/ws$" - "^~ /cool/adminws" - ]; - }; - }; - }; -} diff --git a/modules/nixos/services/nextcloud/default.nix b/modules/nixos/services/nextcloud/default.nix index 24515ff..51195df 100644 --- a/modules/nixos/services/nextcloud/default.nix +++ b/modules/nixos/services/nextcloud/default.nix @@ -4,10 +4,6 @@ let cfg = config.my.services.nextcloud; in { - imports = [ - ./collabora.nix - ]; - options.my.services.nextcloud = with lib; { enable = mkEnableOption "Nextcloud"; maxSize = mkOption { @@ -35,7 +31,7 @@ in config = lib.mkIf cfg.enable { services.nextcloud = { enable = true; - package = pkgs.nextcloud32; + package = pkgs.nextcloud28; hostName = "nextcloud.${config.networking.domain}"; home = "/var/lib/nextcloud"; maxUploadSize = cfg.maxSize; @@ -44,15 +40,11 @@ in adminuser = cfg.admin; adminpassFile = cfg.passwordFile; dbtype = "pgsql"; + dbhost = "/run/postgresql"; }; https = true; - # Automatic PostgreSQL provisioning - database = { - createLocally = true; - }; - settings = { overwriteprotocol = "https"; # Nginx only allows SSL }; @@ -62,16 +54,22 @@ in # Allow using the push service without hard-coding my IP in the configuration bendDomainToLocalhost = true; }; + }; - extraApps = { - inherit (config.services.nextcloud.package.packages.apps) - calendar - contacts - deck - tasks - ; - # notify_push is automatically installed by the module - }; + services.postgresql = { + enable = true; + ensureDatabases = [ "nextcloud" ]; + ensureUsers = [ + { + name = "nextcloud"; + ensureDBOwnership = true; + } + ]; + }; + + systemd.services."nextcloud-setup" = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; }; # The service above configures the domain, no need for my wrapper @@ -89,25 +87,5 @@ in "${config.services.nextcloud.home}/data/appdata_*/preview" ]; }; - - services.fail2ban.jails = { - nextcloud = '' - enabled = true - filter = nextcloud - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/nextcloud.conf".text = '' - [Definition] - _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*) - datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?" - failregex = ^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":""%(_groupsre)s,?\s*"message":"Login failed: - ^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":""%(_groupsre)s,?\s*"message":"Trusted domain error. - ^[^{]*\{%(_groupsre)s,?\s*"remoteAddr":""%(_groupsre)s,?\s*"message":"Two-factor challenge failed: - journalmatch = _SYSTEMD_UNIT=phpfpm-nextcloud.service - ''; - }; }; } diff --git a/modules/nixos/services/nginx/default.nix b/modules/nixos/services/nginx/default.nix index ff530b0..7980ad9 100644 --- a/modules/nixos/services/nginx/default.nix +++ b/modules/nixos/services/nginx/default.nix @@ -17,16 +17,6 @@ let ''; }; - websocketsLocations = mkOption { - type = with types; listOf str; - default = [ ]; - example = [ "/socket" ]; - description = '' - Which locations on this virtual host should be configured for - websockets. - ''; - }; - port = mkOption { type = with types; nullOr port; default = null; @@ -69,15 +59,14 @@ let extraConfig = mkOption { type = types.attrs; # FIXME: forward type of virtualHosts - example = { - extraConfig = '' - add_header X-Clacks-Overhead "GNU Terry Pratchett"; - ''; - - locations."/".extraConfig = '' - client_max_body_size 1G; - ''; - }; + example = litteralExample '' + { + locations."/socket" = { + proxyPass = "http://127.0.0.1:8096/"; + proxyWebsockets = true; + }; + } + ''; default = { }; description = '' Any extra configuration that should be applied to this virtual host. @@ -87,6 +76,10 @@ let }); in { + imports = [ + ./sso + ]; + options.my.services.nginx = with lib; { enable = mkEnableOption "Nginx"; @@ -95,7 +88,7 @@ in type = types.str; example = "/var/lib/acme/creds.env"; description = '' - OVH API key file as an 'EnvironmentFile' (see `systemd.exec(5)`) + Gandi API key file as an 'EnvironmentFile' (see `systemd.exec(5)`) ''; }; }; @@ -107,19 +100,26 @@ in virtualHosts = mkOption { type = types.attrsOf virtualHostOption; default = { }; - example = { - gitea = { - subdomain = "git"; - port = 8080; - }; - dev = { - root = "/var/www/dev"; - }; - jellyfin = { - port = 8096; - websocketsLocations = [ "/socket" ]; - }; - }; + example = litteralExample '' + { + gitea = { + subdomain = "git"; + port = 8080; + }; + dev = { + root = "/var/www/dev"; + }; + jellyfin = { + port = 8096; + extraConfig = { + locations."/socket" = { + proxyPass = "http://127.0.0.1:8096/"; + proxyWebsockets = true; + }; + }; + }; + } + ''; description = '' List of virtual hosts to set-up using default settings. ''; @@ -163,21 +163,25 @@ in }; }; }); - example = { - alice = { - passwordHashFile = "/var/lib/nginx-sso/alice/password-hash.txt"; - totpSecretFile = "/var/lib/nginx-sso/alice/totp-secret.txt"; - }; - }; + example = litteralExample '' + { + alice = { + passwordHashFile = "/var/lib/nginx-sso/alice/password-hash.txt"; + totpSecretFile = "/var/lib/nginx-sso/alice/totp-secret.txt"; + }; + } + ''; description = "Definition of users"; }; groups = mkOption { type = with types; attrsOf (listOf str); - example = { - root = [ "alice" ]; - users = [ "alice" "bob" ]; - }; + example = litteralExample '' + { + root = [ "alice" ]; + users = [ "alice" "bob" ]; + } + ''; description = "Groups of users"; }; }; @@ -199,19 +203,6 @@ in } configured. ''; })) - ++ (lib.flip lib.mapAttrsToList cfg.virtualHosts (_: { subdomain, ... } @ args: - let - proxyPass = [ "port" "socket" ]; - proxyPassUsed = lib.any (v: args.${v} != null) proxyPass; - in - { - assertion = args.websocketsLocations != [ ] -> proxyPassUsed; - message = '' - Subdomain '${subdomain}' can only use 'websocketsLocations' with one of ${ - lib.concatStringsSep ", " (builtins.map (v: "'${v}'") proxyPass) - }. - ''; - })) ++ ( let ports = lib.my.mapFilter @@ -253,18 +244,11 @@ in recommendedOptimisation = true; recommendedProxySettings = true; recommendedTlsSettings = true; + recommendedZstdSettings = true; virtualHosts = let domain = config.networking.domain; - mkProxyPass = { websocketsLocations, ... }: proxyPass: - let - websockets = lib.genAttrs websocketsLocations (_: { - inherit proxyPass; - proxyWebsockets = true; - }); - in - { "/" = { inherit proxyPass; }; } // websockets; mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair "${subdomain}.${domain}" (lib.my.recursiveMerge [ @@ -275,7 +259,8 @@ in } # Proxy to port (lib.optionalAttrs (args.port != null) { - locations = mkProxyPass args "http://127.0.0.1:${toString args.port}"; + locations."/".proxyPass = + "http://127.0.0.1:${toString args.port}"; }) # Serve filesystem content (lib.optionalAttrs (args.root != null) { @@ -283,7 +268,8 @@ in }) # Serve to UNIX socket (lib.optionalAttrs (args.socket != null) { - locations = mkProxyPass args "http://unix:${args.socket}"; + locations."/".proxyPass = + "http://unix:${args.socket}"; }) # Redirect to a different domain (lib.optionalAttrs (args.redirect != null) { @@ -303,7 +289,6 @@ in locations."/" = { extraConfig = - # FIXME: check that X-User is dropped otherwise (args.extraConfig.locations."/".extraConfig or "") + '' # Use SSO auth_request /sso-auth; @@ -437,14 +422,13 @@ in { "${domain}" = { extraDomainNames = [ "*.${domain}" ]; - dnsProvider = "ovh"; - dnsPropagationCheck = false; # OVH is slow + dnsProvider = "gandiv5"; inherit (cfg.acme) credentialsFile; }; }; }; - systemd.services."acme-order-renew-${domain}" = { + systemd.services."acme-${domain}" = { serviceConfig = { Environment = [ # Since I do a "weird" setup with a wildcard CNAME diff --git a/modules/nixos/services/nginx/sso/default.nix b/modules/nixos/services/nginx/sso/default.nix new file mode 100644 index 0000000..4a78282 --- /dev/null +++ b/modules/nixos/services/nginx/sso/default.nix @@ -0,0 +1,89 @@ +# I must override the module to allow having runtime secrets +{ config, lib, pkgs, utils, ... }: +let + cfg = config.services.nginx.sso; + pkg = lib.getBin cfg.package; + confPath = "/var/lib/nginx-sso/config.json"; +in +{ + disabledModules = [ "services/security/nginx-sso.nix" ]; + + + options.services.nginx.sso = with lib; { + enable = mkEnableOption "nginx-sso service"; + + package = mkOption { + type = types.package; + default = pkgs.nginx-sso; + defaultText = "pkgs.nginx-sso"; + description = '' + The nginx-sso package that should be used. + ''; + }; + + configuration = mkOption { + type = types.attrsOf types.unspecified; + default = { }; + example = literalExample '' + { + listen = { addr = "127.0.0.1"; port = 8080; }; + + providers.token.tokens = { + myuser = "MyToken"; + }; + + acl = { + rule_sets = [ + { + rules = [ { field = "x-application"; equals = "MyApp"; } ]; + allow = [ "myuser" ]; + } + ]; + }; + } + ''; + description = '' + nginx-sso configuration + (documentation) + as a Nix attribute set. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.nginx-sso = { + description = "Nginx SSO Backend"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + StateDirectory = "nginx-sso"; + WorkingDirectory = "/var/lib/nginx-sso"; + # The files to be merged might not have the correct permissions + ExecStartPre = ''+${pkgs.writeShellScript "merge-nginx-sso-config" '' + rm -f '${confPath}' + ${utils.genJqSecretsReplacementSnippet cfg.configuration confPath} + + # Fix permissions + chown nginx-sso:nginx-sso ${confPath} + chmod 0600 ${confPath} + '' + }''; + ExecStart = lib.mkForce '' + ${lib.getExe pkg} \ + --config ${confPath} \ + --frontend-dir ${pkg}/share/frontend + ''; + Restart = "always"; + User = "nginx-sso"; + Group = "nginx-sso"; + }; + }; + + users.users.nginx-sso = { + isSystemUser = true; + group = "nginx-sso"; + }; + + users.groups.nginx-sso = { }; + }; +} diff --git a/modules/nixos/services/nix-cache/default.nix b/modules/nixos/services/nix-cache/default.nix index f3a29aa..1ce3161 100644 --- a/modules/nixos/services/nix-cache/default.nix +++ b/modules/nixos/services/nix-cache/default.nix @@ -40,7 +40,7 @@ in inherit (cfg) priority; }; - signKeyPaths = [ cfg.secretKeyFile ]; + signKeyPath = cfg.secretKeyFile; }; my.services.nginx.virtualHosts = { diff --git a/modules/nixos/services/paperless/default.nix b/modules/nixos/services/paperless/default.nix index 1195977..f62879a 100644 --- a/modules/nixos/services/paperless/default.nix +++ b/modules/nixos/services/paperless/default.nix @@ -1,4 +1,4 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.my.services.paperless; in @@ -52,39 +52,91 @@ in mediaDir = lib.mkIf (cfg.documentPath != null) cfg.documentPath; - settings = { - # Use SSO - PAPERLESS_ENABLE_HTTP_REMOTE_USER = true; - PAPERLESS_ENABLE_HTTP_REMOTE_USER_API = true; - PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER"; + settings = + let + paperlessDomain = "paperless.${config.networking.domain}"; + in + { + # Use SSO + PAPERLESS_ENABLE_HTTP_REMOTE_USER = true; + PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER"; - # Security settings - PAPERLESS_URL = "https://paperless.${config.networking.domain}"; - PAPERLESS_USE_X_FORWARD_HOST = true; - PAPERLESS_PROXY_SSL_HEADER = [ "HTTP_X_FORWARDED_PROTO" "https" ]; + # Use PostgreSQL + PAPERLESS_DBHOST = "/run/postgresql"; + PAPERLESS_DBUSER = "paperless"; + PAPERLESS_DBNAME = "paperless"; - # OCR settings - PAPERLESS_OCR_LANGUAGE = "fra+eng"; + # Security settings + PAPERLESS_ALLOWED_HOSTS = paperlessDomain; + PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}"; - # Workers - PAPERLESS_TASK_WORKERS = 3; - PAPERLESS_THREADS_PER_WORKER = 4; + # OCR settings + PAPERLESS_OCR_LANGUAGE = "fra+eng"; - # Misc - PAPERLESS_TIME_ZONE = config.time.timeZone; - PAPERLESS_ADMIN_USER = cfg.username; - }; + # Workers + PAPERLESS_TASK_WORKERS = 3; + PAPERLESS_THREADS_PER_WORKER = 4; + + # Misc + PAPERLESS_TIME_ZONE = config.time.timeZone; + PAPERLESS_ADMIN_USER = cfg.username; + + # Fix classifier hangs + LD_LIBRARY_PATH = "${lib.getLib pkgs.mkl}/lib"; + }; # Admin password passwordFile = cfg.passwordFile; + }; - # Secret key - environmentFile = cfg.secretKeyFile; + systemd.services = { + paperless-scheduler = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; - # Automatic PostgreSQL provisioning - database = { - createLocally = true; + serviceConfig = { + EnvironmentFile = cfg.secretKeyFile; + }; }; + + paperless-consumer = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + serviceConfig = { + EnvironmentFile = cfg.secretKeyFile; + }; + }; + + paperless-web = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + serviceConfig = { + EnvironmentFile = cfg.secretKeyFile; + }; + }; + + paperless-task-queue = { + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + + serviceConfig = { + EnvironmentFile = cfg.secretKeyFile; + }; + }; + }; + + # Set-up database + services.postgresql = { + enable = true; + ensureDatabases = [ "paperless" ]; + ensureUsers = [ + { + name = "paperless"; + ensureDBOwnership = true; + } + ]; }; # Set-up media group @@ -100,7 +152,11 @@ in sso = { enable = true; }; - websocketsLocations = [ "/" ]; + + # Enable websockets on root + extraConfig = { + locations."/".proxyWebsockets = true; + }; }; }; diff --git a/modules/nixos/services/pdf-edit/default.nix b/modules/nixos/services/pdf-edit/default.nix deleted file mode 100644 index d59507b..0000000 --- a/modules/nixos/services/pdf-edit/default.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.my.services.pdf-edit; -in -{ - options.my.services.pdf-edit = with lib; { - enable = mkEnableOption "PDF edition service"; - - port = mkOption { - type = types.port; - default = 8089; - example = 8080; - description = "Internal port for webui"; - }; - - loginFile = mkOption { - type = types.str; - example = "/run/secrets/pdf-edit/login.env"; - description = '' - `SECURITY_INITIALLOGIN_USERNAME` and `SECURITY_INITIALLOGIN_PASSWORD` - defined in the format of 'EnvironmentFile' (see `systemd.exec(5)`). - ''; - }; - }; - - config = lib.mkIf cfg.enable { - services.stirling-pdf = lib.mkIf cfg.enable { - enable = true; - - environment = { - SERVER_PORT = cfg.port; - SECURITY_CSRFDISABLED = "false"; - - SYSTEM_SHOWUPDATE = "false"; # We don't care about update notifications - INSTALL_BOOK_AND_ADVANCED_HTML_OPS = "true"; # Installed by the module - - SECURITY_ENABLELOGIN = "true"; - SECURITY_LOGINATTEMPTCOUNT = "-1"; # Rely on fail2ban instead - }; - - environmentFiles = [ cfg.loginFile ]; - }; - - my.services.nginx.virtualHosts = { - pdf-edit = { - inherit (cfg) port; - - extraConfig = { - # Allow upload of PDF files up to 1G - locations."/".extraConfig = '' - client_max_body_size 1G; - ''; - }; - }; - }; - - services.fail2ban.jails = { - stirling-pdf = '' - enabled = true - filter = stirling-pdf - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/stirling-pdf.conf".text = '' - [Definition] - failregex = ^.*Failed login attempt from IP: $ - journalmatch = _SYSTEMD_UNIT=stirling-pdf.service - ''; - }; - }; -} diff --git a/modules/nixos/services/pirate/default.nix b/modules/nixos/services/pirate/default.nix new file mode 100644 index 0000000..e500b54 --- /dev/null +++ b/modules/nixos/services/pirate/default.nix @@ -0,0 +1,92 @@ +# The total autonomous media delivery system. +# Relevant link [1]. +# +# [1]: https://youtu.be/I26Ql-uX6AM +{ config, lib, ... }: +let + cfg = config.my.services.pirate; + + ports = { + bazarr = 6767; + lidarr = 8686; + radarr = 7878; + sonarr = 8989; + }; + + mkService = service: { + services.${service} = { + enable = true; + group = "media"; + }; + }; + + mkRedirection = service: { + my.services.nginx.virtualHosts = { + ${service} = { + port = ports.${service}; + }; + }; + }; + + mkFail2Ban = service: lib.mkIf cfg.${service}.enable { + services.fail2ban.jails = { + ${service} = '' + enabled = true + filter = ${service} + action = iptables-allports + ''; + }; + + environment.etc = { + "fail2ban/filter.d/${service}.conf".text = '' + [Definition] + failregex = ^.*\|Warn\|Auth\|Auth-Failure ip username .*$ + journalmatch = _SYSTEMD_UNIT=${service}.service + ''; + }; + }; + + mkFullConfig = service: lib.mkIf cfg.${service}.enable (lib.mkMerge [ + (mkService service) + (mkRedirection service) + ]); +in +{ + options.my.services.pirate = { + enable = lib.mkEnableOption "Media automation"; + + bazarr = { + enable = lib.my.mkDisableOption "Bazarr"; + }; + + lidarr = { + enable = lib.my.mkDisableOption "Lidarr"; + }; + + radarr = { + enable = lib.my.mkDisableOption "Radarr"; + }; + + sonarr = { + enable = lib.my.mkDisableOption "Sonarr"; + }; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + { + # Set-up media group + users.groups.media = { }; + } + # Bazarr does not log authentication failures... + (mkFullConfig "bazarr") + # Lidarr for music + (mkFullConfig "lidarr") + (mkFail2Ban "lidarr") + # Radarr for movies + (mkFullConfig "radarr") + (mkFail2Ban "radarr") + # Sonarr for shows + (mkFullConfig "sonarr") + (mkFail2Ban "sonarr") + ]); +} diff --git a/modules/nixos/services/podgrab/default.nix b/modules/nixos/services/podgrab/default.nix index 3ced8d3..5ceebb6 100644 --- a/modules/nixos/services/podgrab/default.nix +++ b/modules/nixos/services/podgrab/default.nix @@ -13,16 +13,7 @@ in example = "/run/secrets/password.env"; description = '' The path to a file containing the PASSWORD environment variable - definition for Podgrab's authentication. - ''; - }; - - dataDir = mkOption { - type = with types; nullOr str; - default = null; - example = "/mnt/podgrab"; - description = '' - Path to the directory to store the podcasts. Use default if null + definition for Podgrab's authentification. ''; }; @@ -38,14 +29,8 @@ in services.podgrab = { enable = true; inherit (cfg) passwordFile port; - - group = "media"; - dataDirectory = lib.mkIf (cfg.dataDir != null) cfg.dataDir; }; - # Set-up media group - users.groups.media = { }; - my.services.nginx.virtualHosts = { podgrab = { inherit (cfg) port; diff --git a/modules/nixos/services/postgresql/default.nix b/modules/nixos/services/postgresql/default.nix index 1dca164..6f51f3e 100644 --- a/modules/nixos/services/postgresql/default.nix +++ b/modules/nixos/services/postgresql/default.nix @@ -14,34 +14,30 @@ in # Let other services enable postgres when they need it (lib.mkIf cfg.enable { services.postgresql = { - package = pkgs.postgresql_17; + package = pkgs.postgresql_13; }; }) # Taken from the manual (lib.mkIf cfg.upgradeScript { + containers.temp-pg.config.services.postgresql = { + enable = true; + package = pkgs.postgresql_13; + }; + environment.systemPackages = let - pgCfg = config.services.postgresql; - newPackage' = pkgs.postgresql_17; - - oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package; - oldData = pgCfg.dataDir; - oldBin = "${if pgCfg.extensions == [] then oldPackage else oldPackage.withPackages pgCfg.extensions}/bin"; - - newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage'; - newData = "/var/lib/postgresql/${newPackage.psqlSchema}"; - newBin = "${if pgCfg.extensions == [] then newPackage else newPackage.withPackages pgCfg.extensions}/bin"; + newpg = config.containers.temp-pg.config.services.postgresql; in [ (pkgs.writeScriptBin "upgrade-pg-cluster" '' #!/usr/bin/env bash - set -eux - export OLDDATA="${oldData}" - export NEWDATA="${newData}" - export OLDBIN="${oldBin}" - export NEWBIN="${newBin}" + set -x + export OLDDATA="${config.services.postgresql.dataDir}" + export NEWDATA="${newpg.dataDir}" + export OLDBIN="${config.services.postgresql.package}/bin" + export NEWBIN="${newpg.package}/bin" if [ "$OLDDATA" -ef "$NEWDATA" ]; then echo "Cannot migrate to same data directory" >&2 @@ -50,21 +46,14 @@ in install -d -m 0700 -o postgres -g postgres "$NEWDATA" cd "$NEWDATA" - sudo -u postgres "$NEWBIN/initdb" -D "$NEWDATA" + sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" systemctl stop postgresql # old one - sudo -u postgres "$NEWBIN/pg_upgrade" \ + sudo -u postgres $NEWBIN/pg_upgrade \ --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ - --old-bindir "$OLDBIN" --new-bindir "$NEWBIN" \ + --old-bindir $OLDBIN --new-bindir $NEWBIN \ "$@" - - cat << EOF - Run the following commands after setting: - services.postgresql.package = pkgs.postgresql_${lib.versions.major newPackage.version} - sudo -u postgres vacuumdb --all --analyze-in-stages - ${newData}/delete_old_cluster.sh - EOF '') ]; }) diff --git a/modules/nixos/services/pyload/default.nix b/modules/nixos/services/pyload/default.nix index 7257d0f..40bf12d 100644 --- a/modules/nixos/services/pyload/default.nix +++ b/modules/nixos/services/pyload/default.nix @@ -39,12 +39,31 @@ in downloadDirectory port ; + }; - # Use media group when downloading files + # Use pyload user/media group when downloading files + systemd.services.pyload = { + serviceConfig = { + User = lib.mkForce "pyload"; + Group = lib.mkForce "media"; + DynamicUser = lib.mkForce false; + }; + }; + + # And make sure the download directory has the correct owners + systemd.tmpfiles.settings.pyload = { + ${cfg.downloadDirectory}.d = { + user = "pyload"; + group = "media"; + }; + }; + + # Set-up pyload user and media group + users.users.pyload = { + isSystemUser = true; group = "media"; }; - # Set-up media group users.groups.media = { }; my.services.nginx.virtualHosts = { @@ -53,20 +72,6 @@ in }; }; - services.fail2ban.jails = { - pyload = '' - enabled = true - filter = pyload - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/pyload.conf".text = '' - [Definition] - failregex = ^.*Login failed for user '.*' \[CLIENT: \]$ - journalmatch = _SYSTEMD_UNIT=pyload.service - ''; - }; + # FIXME: fail2ban }; } diff --git a/modules/nixos/services/rss-bridge/default.nix b/modules/nixos/services/rss-bridge/default.nix index 52b1030..85e37c2 100644 --- a/modules/nixos/services/rss-bridge/default.nix +++ b/modules/nixos/services/rss-bridge/default.nix @@ -11,9 +11,7 @@ in config = lib.mkIf cfg.enable { services.rss-bridge = { enable = true; - config = { - system.enabled_bridges = [ "*" ]; # Whitelist all - }; + whitelist = [ "*" ]; # Whitelist all virtualHost = "rss-bridge.${config.networking.domain}"; }; diff --git a/modules/nixos/services/servarr/autobrr.nix b/modules/nixos/services/servarr/autobrr.nix deleted file mode 100644 index c3370cb..0000000 --- a/modules/nixos/services/servarr/autobrr.nix +++ /dev/null @@ -1,63 +0,0 @@ -# IRC-based indexer -{ config, lib, ... }: -let - cfg = config.my.services.servarr.autobrr; -in -{ - options.my.services.servarr.autobrr = with lib; { - enable = mkEnableOption "autobrr IRC announce tracker" // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = 7474; - example = 8080; - description = "Internal port for webui"; - }; - - sessionSecretFile = mkOption { - type = types.str; - example = "/run/secrets/autobrr-secret.txt"; - description = '' - File containing the session secret. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - services.autobrr = { - enable = true; - - settings = { - inherit (cfg) port; - checkForUpdates = false; - }; - - secretFile = cfg.sessionSecretFile; - }; - - my.services.nginx.virtualHosts = { - autobrr = { - inherit (cfg) port; - websocketsLocations = [ "/api" ]; - }; - }; - - services.fail2ban.jails = { - autobrr = '' - enabled = true - filter = autobrr - action = iptables-allports - ''; - }; - - environment.etc = { - "fail2ban/filter.d/autobrr.conf".text = '' - [Definition] - failregex = "message":"Auth: Failed login attempt username: \[.*\] ip: " - journalmatch = _SYSTEMD_UNIT=autobrr.service - ''; - }; - }; -} diff --git a/modules/nixos/services/servarr/bazarr.nix b/modules/nixos/services/servarr/bazarr.nix deleted file mode 100644 index 637da0c..0000000 --- a/modules/nixos/services/servarr/bazarr.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.my.services.servarr.bazarr; -in -{ - options.my.services.servarr.bazarr = with lib; { - enable = lib.mkEnableOption "Bazarr" // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = 6767; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.bazarr = { - enable = true; - group = "media"; - listenPort = cfg.port; - }; - - # Set-up media group - users.groups.media = { }; - - my.services.nginx.virtualHosts = { - bazarr = { - inherit (cfg) port; - }; - }; - - # Bazarr does not log authentication failures... - }; -} diff --git a/modules/nixos/services/servarr/cross-seed.nix b/modules/nixos/services/servarr/cross-seed.nix deleted file mode 100644 index 74f216a..0000000 --- a/modules/nixos/services/servarr/cross-seed.nix +++ /dev/null @@ -1,96 +0,0 @@ -# Automatic cross-seeding for video media -{ config, lib, ... }: -let - cfg = config.my.services.servarr.cross-seed; -in -{ - options.my.services.servarr.cross-seed = with lib; { - enable = mkEnableOption "cross-seed daemon" // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = 2468; - example = 8080; - description = "Internal port for daemon"; - }; - - linkDirectory = mkOption { - type = types.str; - default = "/data/downloads/complete/links"; - example = "/var/lib/cross-seed/links"; - description = "Link directory"; - }; - - secretSettingsFile = mkOption { - type = types.str; - example = "/run/secrets/cross-seed-secrets.json"; - description = '' - File containing secret settings. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - services.cross-seed = { - enable = true; - group = "media"; - - # Rely on recommended defaults for tracker snatches etc... - useGenConfigDefaults = true; - - settings = { - inherit (cfg) port; - host = "127.0.0.1"; - - # Inject torrents to client directly - action = "inject"; - # Query the client for torrents to match - useClientTorrents = true; - # Use hardlinks - linkType = "hardlink"; - # Use configured link directory - linkDirs = [ cfg.linkDirectory ]; - # Match as many torrents as possible - matchMode = "partial"; - # Cross-seed full season if at least 50% of episodes are already downloaded - seasonFromEpisodes = 0.5; - }; - - settingsFile = cfg.secretSettingsFile; - }; - - systemd.services.cross-seed = { - serviceConfig = { - # Loose umask to make cross-seed links readable by `media` - UMask = "0002"; - }; - }; - - # Set-up media group - users.groups.media = { }; - - my.services.nginx.virtualHosts = { - cross-seed = { - inherit (cfg) port; - }; - }; - - services.fail2ban.jails = { - cross-seed = '' - enabled = true - filter = cross-seed - action = iptables-allports - ''; - }; - - environment.etc = { - "fail2ban/filter.d/cross-seed.conf".text = '' - [Definition] - failregex = ^.*Unauthorized API access attempt to .* from $ - journalmatch = _SYSTEMD_UNIT=cross-seed.service - ''; - }; - }; -} diff --git a/modules/nixos/services/servarr/default.nix b/modules/nixos/services/servarr/default.nix deleted file mode 100644 index dca57cf..0000000 --- a/modules/nixos/services/servarr/default.nix +++ /dev/null @@ -1,23 +0,0 @@ -# The total autonomous media delivery system. -# Relevant link [1]. -# -# [1]: https://youtu.be/I26Ql-uX6AM -{ lib, ... }: -{ - imports = [ - ./autobrr.nix - ./bazarr.nix - ./cross-seed.nix - ./jackett.nix - ./nzbhydra.nix - ./prowlarr.nix - (import ./starr.nix "lidarr") - (import ./starr.nix "radarr") - (import ./starr.nix "readarr") - (import ./starr.nix "sonarr") - ]; - - options.my.services.servarr = { - enableAll = lib.mkEnableOption "media automation suite"; - }; -} diff --git a/modules/nixos/services/servarr/jackett.nix b/modules/nixos/services/servarr/jackett.nix deleted file mode 100644 index 481cd3d..0000000 --- a/modules/nixos/services/servarr/jackett.nix +++ /dev/null @@ -1,41 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.my.services.servarr.jackett; -in -{ - options.my.services.servarr.jackett = with lib; { - enable = lib.mkEnableOption "Jackett" // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = 9117; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.jackett = { - enable = true; - inherit (cfg) port; - }; - - # Jackett wants to eat *all* my RAM if left to its own devices - systemd.services.jackett = { - serviceConfig = { - MemoryHigh = "15%"; - MemoryMax = "25%"; - }; - }; - - my.services.nginx.virtualHosts = { - jackett = { - inherit (cfg) port; - }; - }; - - # Jackett does not log authentication failures... - }; -} diff --git a/modules/nixos/services/servarr/nzbhydra.nix b/modules/nixos/services/servarr/nzbhydra.nix deleted file mode 100644 index 7b63986..0000000 --- a/modules/nixos/services/servarr/nzbhydra.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ config, lib, ... }: -let - cfg = config.my.services.servarr.nzbhydra; -in -{ - options.my.services.servarr.nzbhydra = with lib; { - enable = lib.mkEnableOption "NZBHydra2" // { - default = config.my.services.servarr.enableAll; - }; - }; - - config = lib.mkIf cfg.enable { - services.nzbhydra2 = { - enable = true; - }; - - my.services.nginx.virtualHosts = { - nzbhydra = { - port = 5076; - websocketsLocations = [ "/" ]; - }; - }; - - # NZBHydra2 does not log authentication failures... - }; -} diff --git a/modules/nixos/services/servarr/prowlarr.nix b/modules/nixos/services/servarr/prowlarr.nix deleted file mode 100644 index ce044c6..0000000 --- a/modules/nixos/services/servarr/prowlarr.nix +++ /dev/null @@ -1,53 +0,0 @@ -# Torrent and NZB indexer -{ config, lib, ... }: -let - cfg = config.my.services.servarr.prowlarr; -in -{ - options.my.services.servarr.prowlarr = with lib; { - enable = lib.mkEnableOption "Prowlarr" // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = 9696; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.prowlarr = { - enable = true; - - settings = { - server = { - port = cfg.port; - }; - }; - }; - - my.services.nginx.virtualHosts = { - prowlarr = { - inherit (cfg) port; - }; - }; - - services.fail2ban.jails = { - prowlarr = '' - enabled = true - filter = prowlarr - action = iptables-allports - ''; - }; - - environment.etc = { - "fail2ban/filter.d/prowlarr.conf".text = '' - [Definition] - failregex = ^.*\|Warn\|Auth\|Auth-Failure ip username .*$ - journalmatch = _SYSTEMD_UNIT=prowlarr.service - ''; - }; - }; -} diff --git a/modules/nixos/services/servarr/starr.nix b/modules/nixos/services/servarr/starr.nix deleted file mode 100644 index 2bf7c11..0000000 --- a/modules/nixos/services/servarr/starr.nix +++ /dev/null @@ -1,64 +0,0 @@ -# Templated *arr configuration -starr: -{ config, lib, ... }: -let - cfg = config.my.services.servarr.${starr}; - ports = { - lidarr = 8686; - radarr = 7878; - readarr = 8787; - sonarr = 8989; - }; -in -{ - options.my.services.servarr.${starr} = with lib; { - enable = lib.mkEnableOption (lib.toSentenceCase starr) // { - default = config.my.services.servarr.enableAll; - }; - - port = mkOption { - type = types.port; - default = ports.${starr}; - example = 8080; - description = "Internal port for webui"; - }; - }; - - config = lib.mkIf cfg.enable { - services.${starr} = { - enable = true; - group = "media"; - - settings = { - server = { - port = cfg.port; - }; - }; - }; - - # Set-up media group - users.groups.media = { }; - - my.services.nginx.virtualHosts = { - ${starr} = { - port = cfg.port; - }; - }; - - services.fail2ban.jails = { - ${starr} = '' - enabled = true - filter = ${starr} - action = iptables-allports - ''; - }; - - environment.etc = { - "fail2ban/filter.d/${starr}.conf".text = '' - [Definition] - failregex = ^.*\|Warn\|Auth\|Auth-Failure ip username .*$ - journalmatch = _SYSTEMD_UNIT=${starr}.service - ''; - }; - }; -} diff --git a/modules/nixos/services/tandoor-recipes/default.nix b/modules/nixos/services/tandoor-recipes/default.nix index 4b4ed1a..f5dc2db 100644 --- a/modules/nixos/services/tandoor-recipes/default.nix +++ b/modules/nixos/services/tandoor-recipes/default.nix @@ -26,16 +26,18 @@ in services.tandoor-recipes = { enable = true; - database = { - createLocally = 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}"; @@ -47,25 +49,31 @@ in systemd.services = { tandoor-recipes = { + after = [ "postgresql.service" ]; + requires = [ "postgresql.service" ]; + serviceConfig = { EnvironmentFile = cfg.secretKeyFile; }; }; }; + # Set-up database + services.postgresql = { + enable = true; + ensureDatabases = [ "tandoor_recipes" ]; + ensureUsers = [ + { + name = "tandoor_recipes"; + ensureDBOwnership = true; + } + ]; + }; + my.services.nginx.virtualHosts = { recipes = { inherit (cfg) port; - - extraConfig = { - # Allow bulk upload of recipes for import/export - locations."/".extraConfig = '' - client_max_body_size 0; - ''; - }; }; }; - - # NOTE: unfortunately tandoor-recipes does not log connection failures for fail2ban }; } diff --git a/modules/nixos/services/thelounge/default.nix b/modules/nixos/services/thelounge/default.nix deleted file mode 100644 index e224839..0000000 --- a/modules/nixos/services/thelounge/default.nix +++ /dev/null @@ -1,59 +0,0 @@ -# Web IRC client -{ config, lib, ... }: -let - cfg = config.my.services.thelounge; -in -{ - options.my.services.thelounge = with lib; { - enable = mkEnableOption "The Lounge, a self-hosted web IRC client"; - - port = mkOption { - type = types.port; - default = 9050; - example = 4242; - description = "The port on which The Lounge will listen for incoming HTTP traffic."; - }; - }; - - config = lib.mkIf cfg.enable { - services.thelounge = { - enable = true; - inherit (cfg) port; - - extraConfig = { - reverseProxy = true; - }; - }; - - my.services.nginx.virtualHosts = { - irc = { - inherit (cfg) port; - # Proxy websockets for RPC - websocketsLocations = [ "/" ]; - - extraConfig = { - locations."/".extraConfig = '' - proxy_read_timeout 1d; - ''; - }; - }; - }; - - services.fail2ban.jails = { - thelounge = '' - enabled = true - filter = thelounge - port = http,https - ''; - }; - - environment.etc = { - "fail2ban/filter.d/thelounge.conf".text = '' - [Definition] - failregex = Authentication failed for user .* from $ - Authentication for non existing user attempted from $ - journalmatch = _SYSTEMD_UNIT=thelounge.service - ''; - }; - }; -} diff --git a/modules/nixos/services/transmission/default.nix b/modules/nixos/services/transmission/default.nix index 6a7fbc7..aeb88b7 100644 --- a/modules/nixos/services/transmission/default.nix +++ b/modules/nixos/services/transmission/default.nix @@ -47,7 +47,6 @@ in enable = true; package = pkgs.transmission_4; group = "media"; - webHome = pkgs.trgui-ng-web; downloadDirPermissions = "775"; @@ -66,19 +65,13 @@ in # Proxied behind Nginx. rpc-whitelist-enabled = true; rpc-whitelist = "127.0.0.1"; - - umask = "002"; # To go with `downloadDirPermissions` }; }; + # Transmission wants to eat *all* my RAM if left to its own devices systemd.services.transmission = { serviceConfig = { - # Transmission wants to eat *all* my RAM if left to its own devices MemoryMax = "33%"; - # Avoid errors due to high number of open files. - LimitNOFILE = 1048576; - # Longer stop timeout to finish all torrents - TimeoutStopSec = "5m"; }; }; @@ -97,7 +90,5 @@ in allowedTCPPorts = [ cfg.peerPort ]; allowedUDPPorts = [ cfg.peerPort ]; }; - - # NOTE: unfortunately transmission does not log connection failures for fail2ban }; } diff --git a/modules/nixos/services/vikunja/default.nix b/modules/nixos/services/vikunja/default.nix index 2753da3..9767d00 100644 --- a/modules/nixos/services/vikunja/default.nix +++ b/modules/nixos/services/vikunja/default.nix @@ -30,6 +30,8 @@ in frontendScheme = "https"; frontendHostname = vikunjaDomain; + setupNginx = false; + database = { type = "postgres"; user = "vikunja"; @@ -41,7 +43,7 @@ in service = { # Only allow registration of users through the CLI enableregistration = false; - # Use the host's timezone + # Ues the host's timezone timezone = config.time.timeZone; # Use UNIX socket for serving the API unixsocket = socketPath; @@ -59,11 +61,28 @@ in # This is a weird setup my.services.nginx.virtualHosts = { ${subdomain} = { - socket = socketPath; + # 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 = { + systemd.services.vikunja-api = { serviceConfig = { # Use a system user to simplify using the CLI DynamicUser = lib.mkForce false; @@ -99,7 +118,5 @@ in config.services.vikunja.settings.files.basepath ]; }; - - # NOTE: unfortunately vikunja does not log connection failures for fail2ban }; } diff --git a/modules/nixos/services/wireguard/default.nix b/modules/nixos/services/wireguard/default.nix index 840ac33..26e54e0 100644 --- a/modules/nixos/services/wireguard/default.nix +++ b/modules/nixos/services/wireguard/default.nix @@ -13,7 +13,7 @@ let porthos = { clientNum = 1; publicKey = "PLdgsizztddri0LYtjuNHr5r2E8D+yI+gM8cm5WDfHQ="; - externalIp = "37.187.146.15"; + externalIp = "91.121.177.163"; }; # "Clients" @@ -206,7 +206,7 @@ in ]; } - # Additional interface is only used to get access to "LAN" from wireguard + # Additional inteface is only used to get access to "LAN" from wireguard (lib.mkIf cfg.internal.enable { networking.wg-quick.interfaces."${cfg.internal.name}" = mkInterface [ "${cfg.net.v4.subnet}.0/${toString cfg.net.v4.mask}" diff --git a/modules/nixos/services/woodpecker/agent-exec/default.nix b/modules/nixos/services/woodpecker/agent-exec/default.nix index 24161b0..7ae21c8 100644 --- a/modules/nixos/services/woodpecker/agent-exec/default.nix +++ b/modules/nixos/services/woodpecker/agent-exec/default.nix @@ -44,8 +44,6 @@ in serviceConfig = { # Same option as upstream, without @setuid SystemCallFilter = lib.mkForce "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap"; - # NodeJS requires RWX memory... - MemoryDenyWriteExecute = lib.mkForce false; BindPaths = [ "/nix/var/nix/daemon-socket/socket" diff --git a/modules/nixos/services/woodpecker/default.nix b/modules/nixos/services/woodpecker/default.nix index 012eaae..34ffca6 100644 --- a/modules/nixos/services/woodpecker/default.nix +++ b/modules/nixos/services/woodpecker/default.nix @@ -8,12 +8,6 @@ options.my.services.woodpecker = with lib; { enable = mkEnableOption "Woodpecker CI"; - forge = mkOption { - type = types.enum [ "gitea" "forgejo" ]; - default = "forgejo"; - example = "gitea"; - description = "Which Forge to connect to"; - }; runners = mkOption { type = with types; listOf (enum [ "exec" "docker" ]); default = [ ]; diff --git a/modules/nixos/services/woodpecker/server/default.nix b/modules/nixos/services/woodpecker/server/default.nix index caf0179..f02a5c5 100644 --- a/modules/nixos/services/woodpecker/server/default.nix +++ b/modules/nixos/services/woodpecker/server/default.nix @@ -17,15 +17,15 @@ in WOODPECKER_GRPC_ADDR = ":${toString cfg.rpcPort}"; WOODPECKER_GITEA = "true"; - WOODPECKER_GITEA_URL = config.services.${cfg.forge}.settings.server.ROOT_URL; + WOODPECKER_GITEA_URL = config.services.gitea.settings.server.ROOT_URL; WOODPECKER_LOG_LEVEL = "debug"; }; }; systemd.services.woodpecker-server = { - after = [ "postgresql.target" ]; - requires = [ "postgresql.target" ]; + after = [ "postgresql.service" ]; + requires = [ "postgresql.service" ]; serviceConfig = { # Set username for DB access diff --git a/modules/nixos/system/nix/default.nix b/modules/nixos/system/nix/default.nix index 12a395e..365e84f 100644 --- a/modules/nixos/system/nix/default.nix +++ b/modules/nixos/system/nix/default.nix @@ -22,10 +22,6 @@ in options.my.system.nix = with lib; { enable = my.mkDisableOption "nix configuration"; - gc = { - enable = my.mkDisableOption "nix GC configuration"; - }; - cache = { selfHosted = my.mkDisableOption "self-hosted cache"; }; @@ -58,30 +54,17 @@ in nix = { package = pkgs.nix; + # FIXME: waiting on https://github.com/NixOS/nixpkgs/pull/146515 + # FIXME: look at https://github.com/SuperSandro2000/nixos-modules/blob/master/modules/nix.nix settings = { + # I like XDG-compliance + use-xdg-base-directories = true; + experimental-features = [ "nix-command" "flakes" ]; - # Trusted users are equivalent to root, and might as well allow wheel - trusted-users = [ "root" "@wheel" ]; }; }; } - (lib.mkIf cfg.gc.enable { - nix.gc = { - automatic = true; - - # Every week, with some wiggle room - dates = "weekly"; - randomizedDelaySec = "10min"; - - # Use a persistent timer for e.g: laptops - persistent = true; - - # Delete old profiles automatically after 15 days - options = "--delete-older-than 15d"; - }; - }) - (lib.mkIf cfg.cache.selfHosted { nix = { settings = { diff --git a/modules/nixos/system/packages/default.nix b/modules/nixos/system/packages/default.nix index 6a78ff6..5c29aa0 100644 --- a/modules/nixos/system/packages/default.nix +++ b/modules/nixos/system/packages/default.nix @@ -1,5 +1,5 @@ # Common packages -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let cfg = config.my.system.packages; in @@ -13,11 +13,13 @@ in }; config = lib.mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + vim + wget + ]; + programs = { - vim = { - enable = true; - defaultEditor = true; # Modal editing is life - }; + vim.defaultEditor = true; # Modal editing is life zsh = { enable = true; # Use integrations diff --git a/overlays/downgrade-transmission/default.nix b/overlays/downgrade-transmission/default.nix deleted file mode 100644 index 9d3fc8a..0000000 --- a/overlays/downgrade-transmission/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -self: prev: -{ - transmission_4 = prev.transmission_4.overrideAttrs (_: { - version = "4.0.5"; - - src = self.fetchFromGitHub { - owner = "transmission"; - repo = "transmission"; - rev = "4.0.5"; - hash = "sha256-gd1LGAhMuSyC/19wxkoE2mqVozjGPfupIPGojKY0Hn4="; - fetchSubmodules = true; - }; - }); -} diff --git a/overlays/gruvbox-nvim-better-diff/colours.patch b/overlays/gruvbox-nvim-better-diff/colours.patch new file mode 100644 index 0000000..5b0d61a --- /dev/null +++ b/overlays/gruvbox-nvim-better-diff/colours.patch @@ -0,0 +1,28 @@ +From 416b3c9c5e783d173ac0fd5310a76c1b144b92c1 Mon Sep 17 00:00:00 2001 +From: eeeXun +Date: Thu, 19 Oct 2023 02:34:12 +0800 +Subject: Use better diff colours + +--- + README.md | 3 ++- + lua/gruvbox.lua | 7 ++++--- + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/lua/gruvbox.lua b/lua/gruvbox.lua +index ceba0735..a319fc6a 100644 +--- a/lua/gruvbox.lua ++++ b/lua/gruvbox.lua +@@ -360,9 +361,9 @@ local function get_groups() + PmenuSel = { fg = colors.bg2, bg = colors.blue, bold = config.bold }, + PmenuSbar = { bg = colors.bg2 }, + PmenuThumb = { bg = colors.bg4 }, +- DiffDelete = { bg = colors.dark_red }, +- DiffAdd = { bg = colors.dark_green }, +- DiffChange = { bg = colors.dark_aqua }, +- DiffText = { bg = colors.yellow, fg = colors.bg0 }, ++ DiffDelete = { fg = colors.red }, ++ DiffAdd = { fg = colors.green }, ++ DiffChange = { fg = colors.aqua }, ++ DiffText = { fg = colors.yellow, bg = colors.bg0 }, + SpellCap = { link = "GruvboxBlueUnderline" }, + SpellBad = { link = "GruvboxRedUnderline" }, diff --git a/overlays/gruvbox-nvin-expose-palette/default.nix b/overlays/gruvbox-nvim-better-diff/default.nix similarity index 100% rename from overlays/gruvbox-nvin-expose-palette/default.nix rename to overlays/gruvbox-nvim-better-diff/default.nix diff --git a/overlays/gruvbox-nvim-better-diff/generated.nix b/overlays/gruvbox-nvim-better-diff/generated.nix new file mode 100644 index 0000000..82a18c2 --- /dev/null +++ b/overlays/gruvbox-nvim-better-diff/generated.nix @@ -0,0 +1,10 @@ +{ ... }: + +_final: prev: { + gruvbox-nvim = prev.gruvbox-nvim.overrideAttrs (oa: { + patches = (oa.patches or [ ]) ++ [ + # Inspired by https://github.com/ellisonleao/gruvbox.nvim/pull/291 + ./colours.patch + ]; + }); +} diff --git a/overlays/gruvbox-nvim-treesitter-fix/default.nix b/overlays/gruvbox-nvim-treesitter-fix/default.nix new file mode 100644 index 0000000..832e71d --- /dev/null +++ b/overlays/gruvbox-nvim-treesitter-fix/default.nix @@ -0,0 +1,4 @@ +self: prev: +{ + vimPlugins = prev.vimPlugins.extend (self.callPackage ./generated.nix { }); +} diff --git a/overlays/gruvbox-nvim-treesitter-fix/generated.nix b/overlays/gruvbox-nvim-treesitter-fix/generated.nix new file mode 100644 index 0000000..5a18d62 --- /dev/null +++ b/overlays/gruvbox-nvim-treesitter-fix/generated.nix @@ -0,0 +1,14 @@ +{ fetchFromGitHub }: + +_final: prev: { + gruvbox-nvim = prev.gruvbox-nvim.overrideAttrs (_: { + version = "2024-01-29"; + + src = fetchFromGitHub { + owner = "ellisonleao"; + repo = "gruvbox.nvim"; + rev = "6e4027ae957cddf7b193adfaec4a8f9e03b4555f"; + sha256 = "sha256-jWnrRy/PT7D0UcPGL+XTbKHWvS0ixvbyqPtTzG9HY84="; + }; + }); +} diff --git a/overlays/gruvbox-nvin-expose-palette/generated.nix b/overlays/gruvbox-nvin-expose-palette/generated.nix deleted file mode 100644 index c52ad04..0000000 --- a/overlays/gruvbox-nvin-expose-palette/generated.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ fetchpatch, ... }: - -_final: prev: { - gruvbox-nvim = prev.gruvbox-nvim.overrideAttrs (oa: { - patches = (oa.patches or [ ]) ++ [ - # https://github.com/ellisonleao/gruvbox.nvim/pull/319 - (fetchpatch { - name = "expose-color-palette.patch"; - url = "https://github.com/ellisonleao/gruvbox.nvim/commit/07a493ba4f8b650aab9ed9e486caa89822be0996.patch"; - hash = "sha256-iGwt8qIHe2vaiAUcpaUxyGlM472F89vobTdQ7CF/H70="; - }) - ]; - }); -} diff --git a/pkgs/bw-pass/bw-pass b/pkgs/bw-pass/bw-pass index 0e974b7..124714a 100755 --- a/pkgs/bw-pass/bw-pass +++ b/pkgs/bw-pass/bw-pass @@ -66,7 +66,7 @@ query_password() { printf '%s\n' "$PASSWORD" } -if [ $# -lt 1 ] || [ $# -gt 2 ]; then +if [ $# -lt 1 ] || [ $# -gt 2 ]; then usage exit 1 fi diff --git a/pkgs/change-audio/change-audio b/pkgs/change-audio/change-audio index 5a1fb9c..612fecf 100755 --- a/pkgs/change-audio/change-audio +++ b/pkgs/change-audio/change-audio @@ -62,7 +62,7 @@ do_toggle() { } case "$1" in - up | down) + up|down) do_change_volume "$@" ;; toggle) diff --git a/pkgs/comma/comma b/pkgs/comma/comma index b03a7f2..4367a26 100755 --- a/pkgs/comma/comma +++ b/pkgs/comma/comma @@ -12,9 +12,9 @@ usage() { find_program() { local CANDIDATE - CANDIDATE="$(nix-locate --minimal --at-root --whole-name "/bin/$1")" + CANDIDATE="$(nix-locate --top-level --minimal --at-root --whole-name "/bin/$1")" if [ "$(printf '%s\n' "$CANDIDATE" | wc -l)" -gt 1 ]; then - CANDIDATE="$(printf '%s' "$CANDIDATE" | "${COMMA_PICKER:-fzf-tmux}")" + CANDIDATE="$(printf '%s' "$CANDIDATE" | fzf-tmux)" fi printf '%s' "$CANDIDATE" } diff --git a/pkgs/diff-flake/diff-flake b/pkgs/diff-flake/diff-flake index a2a3513..0572b4e 100755 --- a/pkgs/diff-flake/diff-flake +++ b/pkgs/diff-flake/diff-flake @@ -81,23 +81,23 @@ parse_args() { shift case "$opt" in - -h | --help) + -h|--help) usage exit ;; - -f | --flake-output) + -f|--flake-output) FLAKE_OUTPUTS+=("$1") shift ;; - -o | --output) + -o|--output) OUTPUT_FILE="$1" shift ;; - -n | --new-rev) + -n|--new-rev) NEW_REV="$(git rev-parse "$1")" shift ;; - -p | --previous-rev) + -p|--previous-rev) PREVIOUS_REV="$(git rev-parse "$1")" shift ;; @@ -157,7 +157,7 @@ list_dev_shells() { } diff_output() { - local PREV NEW + local PREV NEW; PREV="$(mktemp --dry-run)" NEW="$(mktemp --dry-run)" @@ -169,7 +169,7 @@ diff_output() { printf 'Closure diff for `%s`:\n```\n' "$1" nix store diff-closures "$PREV" "$NEW" | sanitize_output printf '```\n\n' - } >>"$OUTPUT_FILE" + } >> "$OUTPUT_FILE" } parse_args "$@" diff --git a/pkgs/lohr/default.nix b/pkgs/lohr/default.nix index d8545e0..ddeac7a 100644 --- a/pkgs/lohr/default.nix +++ b/pkgs/lohr/default.nix @@ -1,16 +1,16 @@ { lib, fetchFromGitHub, rustPlatform }: rustPlatform.buildRustPackage rec { pname = "lohr"; - version = "0.4.6"; + version = "0.4.5"; src = fetchFromGitHub { owner = "alarsyo"; repo = "lohr"; rev = "v${version}"; - hash = "sha256-dunQgtap+XCK5LoSyOqIY/6p6HizBeiyPWNuCffwjDU="; + hash = "sha256-p6E/r+OxFTpxDpOKSlacOxvRLfHSKg1mHNAfTytfqDY="; }; - cargoHash = "sha256-R3/N/43+bGx6acE/rhBcrk6kS5zQu8NJ1sVvKJJkK9w="; + cargoHash = "sha256-hext0S0o9D9pN9epzXtD5dwAYMPCLpBBOBT4FX0mTMk="; meta = with lib; { description = "Git mirroring daemon"; diff --git a/pkgs/osc52/osc52 b/pkgs/osc52/osc52 index de3a982..f64ccb6 100755 --- a/pkgs/osc52/osc52 +++ b/pkgs/osc52/osc52 @@ -15,7 +15,7 @@ usage() { exec 1>&2 fi - cat <&2 fi - cat < Send a notification (title and message) to the host system using the OSC 777 escape sequence: diff --git a/pkgs/unbound-zones-adblock/default.nix b/pkgs/unbound-zones-adblock/default.nix index 11a6c90..642ac41 100644 --- a/pkgs/unbound-zones-adblock/default.nix +++ b/pkgs/unbound-zones-adblock/default.nix @@ -1,7 +1,7 @@ { lib, gawk, stdenvNoCC, stevenblack-blocklist }: stdenvNoCC.mkDerivation { name = "unbound-zones-adblock"; - inherit (stevenblack-blocklist) version; + version = stevenblack-blocklist.rev; src = stevenblack-blocklist; @@ -30,7 +30,7 @@ stdenvNoCC.mkDerivation { description = "Unified host lists, ready to be used by unbound"; longDescription = '' This is a simple derivation based on StevenBlack's unified hosts list. - The files have been modified for easy use with unbound. + The files have been modified for easy use wih unbound. ''; homepage = "https://github.com/StevenBlack/hosts"; license = licenses.mit; diff --git a/pkgs/zsh-done/default.nix b/pkgs/zsh-done/default.nix index 8fac813..bddc6c1 100644 --- a/pkgs/zsh-done/default.nix +++ b/pkgs/zsh-done/default.nix @@ -2,13 +2,13 @@ stdenvNoCC.mkDerivation rec { pname = "zsh-done"; - version = "0.1.1"; + version = "0.1.0"; src = fetchFromGitHub { owner = "ambroisie"; repo = "zsh-done"; rev = "v${version}"; - hash = "sha256-dyhPhoMrAfDWtrBX5TA+B3G7QZ7gBhoDGNOEqGsCBQU="; + hash = "sha256-DC7urJDXPP9vBYABrJF5KZ4HfMbrpHIVogSmEB8PWLA="; }; dontConfigure = true; @@ -26,7 +26,7 @@ stdenvNoCC.mkDerivation rec { description = '' A zsh plug-in to receive notifications when long processes finish ''; - homepage = "https://git.belanyi.fr/ambroisie/zsh-done"; + homepage = "https://gitea.belanyi.fr/ambroisie/zsh-done"; license = licenses.mit; platforms = platforms.unix; maintainers = with maintainers; [ ambroisie ]; diff --git a/templates/c++-cmake/.envrc b/templates/c++-cmake/.envrc old mode 100755 new mode 100644 index 390d06d..de77fcb --- a/templates/c++-cmake/.envrc +++ b/templates/c++-cmake/.envrc @@ -1,4 +1,3 @@ -# shellcheck shell=bash if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" fi diff --git a/templates/c++-cmake/.woodpecker/check.yml b/templates/c++-cmake/.woodpecker/check.yml index 272c0e4..628e491 100644 --- a/templates/c++-cmake/.woodpecker/check.yml +++ b/templates/c++-cmake/.woodpecker/check.yml @@ -1,30 +1,25 @@ labels: - backend: local + type: exec steps: -- name: pre-commit check - image: bash - commands: - - nix develop --command pre-commit run --all - - name: nix flake check image: bash commands: - nix flake check -- name: notify +- name: notifiy image: bash - environment: - ADDRESS: - from_secret: matrix_homeserver - ROOM: - from_secret: matrix_roomid - USER: - from_secret: matrix_username - PASS: - from_secret: matrix_password + secrets: + - source: matrix_homeserver + target: address + - source: matrix_roomid + target: room + - source: matrix_username + target: user + - source: matrix_password + target: pass commands: - - nix run github:ambroisie/matrix-notifier + - nix run '.#matrix-notifier' when: status: - failure diff --git a/templates/c++-cmake/flake.nix b/templates/c++-cmake/flake.nix index 7796f5e..cb468e7 100644 --- a/templates/c++-cmake/flake.nix +++ b/templates/c++-cmake/flake.nix @@ -16,18 +16,19 @@ ref = "nixos-unstable"; }; - git-hooks = { + pre-commit-hooks = { type = "github"; owner = "cachix"; - repo = "git-hooks.nix"; + repo = "pre-commit-hooks.nix"; ref = "master"; inputs = { + flake-utils.follows = "futils"; nixpkgs.follows = "nixpkgs"; }; }; }; - outputs = { self, futils, nixpkgs, git-hooks }: + outputs = { self, futils, nixpkgs, pre-commit-hooks }: { overlays = { default = final: _prev: { @@ -51,7 +52,7 @@ meta = with lib; { description = "A C++ project"; - homepage = "https://git.belanyi.fr/ambroisie/project"; + homepage = "https://gitea.belanyi.fr/ambroisie/project"; license = licenses.mit; maintainers = with maintainers; [ ambroisie ]; platforms = platforms.unix; @@ -68,7 +69,7 @@ ]; }; - pre-commit = git-hooks.lib.${system}.run { + pre-commit = pre-commit-hooks.lib.${system}.run { src = self; hooks = { @@ -91,12 +92,12 @@ devShells = { default = pkgs.mkShell { - inputsFrom = [ - self.packages.${system}.project + inputsFrom = with self.packages.${system}; [ + project ]; packages = with pkgs; [ - self.checks.${system}.pre-commit.enabledPackages + clang-tools ]; inherit (pre-commit) shellHook; diff --git a/templates/c++-cmake/tests/unit/CMakeLists.txt b/templates/c++-cmake/tests/unit/CMakeLists.txt index 266e3e3..bb94448 100644 --- a/templates/c++-cmake/tests/unit/CMakeLists.txt +++ b/templates/c++-cmake/tests/unit/CMakeLists.txt @@ -1,15 +1,15 @@ find_package(GTest) -if(${GTest_FOUND}) - include(GoogleTest) +if (${GTest_FOUND}) +include(GoogleTest) - add_executable(dummy_test dummy_test.cc) - target_link_libraries(dummy_test PRIVATE common_options) +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 - ) +target_link_libraries(dummy_test PRIVATE + GTest::gtest + GTest::gtest_main +) - gtest_discover_tests(dummy_test) -endif() +gtest_discover_tests(dummy_test) +endif (${GTest_FOUND}) diff --git a/templates/c++-meson/.envrc b/templates/c++-meson/.envrc index 390d06d..de77fcb 100644 --- a/templates/c++-meson/.envrc +++ b/templates/c++-meson/.envrc @@ -1,4 +1,3 @@ -# shellcheck shell=bash if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" fi diff --git a/templates/c++-meson/.woodpecker/check.yml b/templates/c++-meson/.woodpecker/check.yml index 272c0e4..628e491 100644 --- a/templates/c++-meson/.woodpecker/check.yml +++ b/templates/c++-meson/.woodpecker/check.yml @@ -1,30 +1,25 @@ labels: - backend: local + type: exec steps: -- name: pre-commit check - image: bash - commands: - - nix develop --command pre-commit run --all - - name: nix flake check image: bash commands: - nix flake check -- name: notify +- name: notifiy image: bash - environment: - ADDRESS: - from_secret: matrix_homeserver - ROOM: - from_secret: matrix_roomid - USER: - from_secret: matrix_username - PASS: - from_secret: matrix_password + secrets: + - source: matrix_homeserver + target: address + - source: matrix_roomid + target: room + - source: matrix_username + target: user + - source: matrix_password + target: pass commands: - - nix run github:ambroisie/matrix-notifier + - nix run '.#matrix-notifier' when: status: - failure diff --git a/templates/c++-meson/flake.nix b/templates/c++-meson/flake.nix index cb14eb5..9cfed0d 100644 --- a/templates/c++-meson/flake.nix +++ b/templates/c++-meson/flake.nix @@ -16,18 +16,19 @@ ref = "nixos-unstable"; }; - git-hooks = { + pre-commit-hooks = { type = "github"; owner = "cachix"; - repo = "git-hooks.nix"; + repo = "pre-commit-hooks.nix"; ref = "master"; inputs = { + flake-utils.follows = "futils"; nixpkgs.follows = "nixpkgs"; }; }; }; - outputs = { self, futils, nixpkgs, git-hooks }: + outputs = { self, futils, nixpkgs, pre-commit-hooks }: { overlays = { default = final: _prev: { @@ -51,7 +52,7 @@ meta = with lib; { description = "A C++ project"; - homepage = "https://git.belanyi.fr/ambroisie/project"; + homepage = "https://gitea.belanyi.fr/ambroisie/project"; license = licenses.mit; maintainers = with maintainers; [ ambroisie ]; platforms = platforms.unix; @@ -68,7 +69,7 @@ ]; }; - pre-commit = git-hooks.lib.${system}.run { + pre-commit = pre-commit-hooks.lib.${system}.run { src = self; hooks = { @@ -91,12 +92,12 @@ devShells = { default = pkgs.mkShell { - inputsFrom = [ - self.packages.${system}.project + inputsFrom = with self.packages.${system}; [ + project ]; packages = with pkgs; [ - self.checks.${system}.pre-commit.enabledPackages + clang-tools ]; inherit (pre-commit) shellHook; diff --git a/templates/default.nix b/templates/default.nix index 51864cd..f58fd72 100644 --- a/templates/default.nix +++ b/templates/default.nix @@ -5,14 +5,6 @@ }; "c++-meson" = { path = ./c++-meson; - description = "A C++ project using Meson"; - }; - "python-uv" = { - path = ./python-uv; - description = "A Python project using uv"; - }; - "rust-cargo" = { - path = ./rust-cargo; - description = "A Rust project using Cargo"; + description = "A C++ project using CMake"; }; } diff --git a/templates/python-uv/.envrc b/templates/python-uv/.envrc deleted file mode 100644 index 390d06d..0000000 --- a/templates/python-uv/.envrc +++ /dev/null @@ -1,6 +0,0 @@ -# shellcheck shell=bash -if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" -fi - -use flake diff --git a/templates/python-uv/.gitignore b/templates/python-uv/.gitignore deleted file mode 100644 index c79d1e8..0000000 --- a/templates/python-uv/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Virtual environments -.venv - -# Nix generated files -/.pre-commit-config.yaml -/result diff --git a/templates/python-uv/.woodpecker/check.yml b/templates/python-uv/.woodpecker/check.yml deleted file mode 100644 index 272c0e4..0000000 --- a/templates/python-uv/.woodpecker/check.yml +++ /dev/null @@ -1,31 +0,0 @@ -labels: - backend: local - -steps: -- name: pre-commit check - image: bash - commands: - - nix develop --command pre-commit run --all - -- name: nix flake check - image: bash - commands: - - nix flake check - -- name: notify - image: bash - environment: - ADDRESS: - from_secret: matrix_homeserver - ROOM: - from_secret: matrix_roomid - USER: - from_secret: matrix_username - PASS: - from_secret: matrix_password - commands: - - nix run github:ambroisie/matrix-notifier - when: - status: - - failure - - success diff --git a/templates/python-uv/flake.nix b/templates/python-uv/flake.nix deleted file mode 100644 index 5059e64..0000000 --- a/templates/python-uv/flake.nix +++ /dev/null @@ -1,112 +0,0 @@ -{ - description = "A Python project"; - - inputs = { - futils = { - type = "github"; - owner = "numtide"; - repo = "flake-utils"; - ref = "main"; - }; - - nixpkgs = { - type = "github"; - owner = "NixOS"; - repo = "nixpkgs"; - ref = "nixos-unstable"; - }; - - git-hooks = { - type = "github"; - owner = "cachix"; - repo = "git-hooks.nix"; - ref = "master"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - }; - - outputs = { self, futils, nixpkgs, git-hooks }: - { - overlays = { - default = final: _prev: { - project = with final; python3.pkgs.buildPythonApplication { - pname = "project"; - version = (final.lib.importTOML ./pyproject.toml).project.version; - pyproject = true; - - src = self; - - build-system = with python3.pkgs; [ setuptools ]; - - pythonImportsCheck = [ "project" ]; - - meta = with lib; { - description = "A Python project"; - homepage = "https://git.belanyi.fr/ambroisie/project"; - license = licenses.mit; - maintainers = with maintainers; [ ambroisie ]; - }; - }; - }; - }; - } // futils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ - self.overlays.default - ]; - }; - - pre-commit = git-hooks.lib.${system}.run { - src = self; - - hooks = { - mypy = { - enable = true; - }; - - nixpkgs-fmt = { - enable = true; - }; - - ruff = { - enable = true; - }; - - ruff-format = { - enable = true; - }; - }; - }; - in - { - checks = { - inherit (self.packages.${system}) project; - - inherit pre-commit; - }; - - devShells = { - default = pkgs.mkShell { - inputsFrom = [ - self.packages.${system}.project - ]; - - packages = with pkgs; [ - uv - self.checks.${system}.pre-commit.enabledPackages - ]; - - inherit (pre-commit) shellHook; - }; - }; - - packages = futils.lib.flattenTree { - default = pkgs.project; - inherit (pkgs) project; - }; - }); -} diff --git a/templates/python-uv/pyproject.toml b/templates/python-uv/pyproject.toml deleted file mode 100644 index 7b2d896..0000000 --- a/templates/python-uv/pyproject.toml +++ /dev/null @@ -1,17 +0,0 @@ -[build-system] -requires = ["setuptools"] -build-backend = "setuptools.build_meta" - - -[project] -name = "project" -version = "0.0.0" -description = "project description" -requires-python = ">=3.12" -dependencies = [] - -[project.scripts] -project = "project:main" - -[dependency-groups] -dev = [] diff --git a/templates/python-uv/src/project/__init__.py b/templates/python-uv/src/project/__init__.py deleted file mode 100644 index b06117d..0000000 --- a/templates/python-uv/src/project/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -def main() -> None: - print("Hello, world!") diff --git a/templates/rust-cargo/.envrc b/templates/rust-cargo/.envrc deleted file mode 100644 index 390d06d..0000000 --- a/templates/rust-cargo/.envrc +++ /dev/null @@ -1,6 +0,0 @@ -# shellcheck shell=bash -if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" -fi - -use flake diff --git a/templates/rust-cargo/.gitignore b/templates/rust-cargo/.gitignore deleted file mode 100644 index 5f360ff..0000000 --- a/templates/rust-cargo/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# Rust build directory -/target - -# Nix generated files -/.pre-commit-config.yaml -/result diff --git a/templates/rust-cargo/.woodpecker/check.yml b/templates/rust-cargo/.woodpecker/check.yml deleted file mode 100644 index 272c0e4..0000000 --- a/templates/rust-cargo/.woodpecker/check.yml +++ /dev/null @@ -1,31 +0,0 @@ -labels: - backend: local - -steps: -- name: pre-commit check - image: bash - commands: - - nix develop --command pre-commit run --all - -- name: nix flake check - image: bash - commands: - - nix flake check - -- name: notify - image: bash - environment: - ADDRESS: - from_secret: matrix_homeserver - ROOM: - from_secret: matrix_roomid - USER: - from_secret: matrix_username - PASS: - from_secret: matrix_password - commands: - - nix run github:ambroisie/matrix-notifier - when: - status: - - failure - - success diff --git a/templates/rust-cargo/Cargo.lock b/templates/rust-cargo/Cargo.lock deleted file mode 100644 index 4f9c86e..0000000 --- a/templates/rust-cargo/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "project" -version = "0.0.0" diff --git a/templates/rust-cargo/Cargo.toml b/templates/rust-cargo/Cargo.toml deleted file mode 100644 index 4dfdc0b..0000000 --- a/templates/rust-cargo/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "project" -version = "0.0.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/templates/rust-cargo/flake.nix b/templates/rust-cargo/flake.nix deleted file mode 100644 index efd8358..0000000 --- a/templates/rust-cargo/flake.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - description = "A Rust project"; - - inputs = { - futils = { - type = "github"; - owner = "numtide"; - repo = "flake-utils"; - ref = "main"; - }; - - nixpkgs = { - type = "github"; - owner = "NixOS"; - repo = "nixpkgs"; - ref = "nixos-unstable"; - }; - - git-hooks = { - type = "github"; - owner = "cachix"; - repo = "git-hooks.nix"; - ref = "master"; - inputs = { - nixpkgs.follows = "nixpkgs"; - }; - }; - }; - - outputs = { self, futils, nixpkgs, git-hooks }: - { - overlays = { - default = final: _prev: { - project = with final; rustPlatform.buildRustPackage { - pname = "project"; - version = (final.lib.importTOML ./Cargo.toml).package.version; - - src = self; - - cargoLock = { - lockFile = "${self}/Cargo.lock"; - }; - - meta = with lib; { - description = "A Rust project"; - homepage = "https://git.belanyi.fr/ambroisie/project"; - license = licenses.mit; - maintainers = with maintainers; [ ambroisie ]; - }; - }; - }; - }; - } // futils.lib.eachDefaultSystem (system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ - self.overlays.default - ]; - }; - - pre-commit = git-hooks.lib.${system}.run { - src = self; - - hooks = { - clippy = { - enable = true; - settings = { - denyWarnings = true; - }; - }; - - nixpkgs-fmt = { - enable = true; - }; - - rustfmt = { - enable = true; - }; - }; - }; - in - { - checks = { - inherit (self.packages.${system}) project; - }; - - devShells = { - default = pkgs.mkShell { - inputsFrom = [ - self.packages.${system}.project - ]; - - packages = with pkgs; [ - rust-analyzer - self.checks.${system}.pre-commit.enabledPackages - ]; - - RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; - - inherit (pre-commit) shellHook; - }; - }; - - packages = futils.lib.flattenTree { - default = pkgs.project; - inherit (pkgs) project; - }; - }); -} diff --git a/templates/rust-cargo/rustfmt.toml b/templates/rust-cargo/rustfmt.toml deleted file mode 100644 index e69de29..0000000 diff --git a/templates/rust-cargo/src/main.rs b/templates/rust-cargo/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/templates/rust-cargo/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -}