diff --git a/SwarselSystems.org b/SwarselSystems.org index 0dd813a..b9d1aff 100644 --- a/SwarselSystems.org +++ b/SwarselSystems.org @@ -10383,7 +10383,7 @@ Used here: [[#h:877c9401-a354-4e44-a235-db1a90d19e00][General org-mode]] #+begin_src emacs-lisp (defun swarsel/org-mode-setup () - (org-indent-mode) + ;; (org-indent-mode) (variable-pitch-mode 1) ;;(auto-fill-mode 0) ;; (setq display-line-numbers-type 'relative @@ -11854,6 +11854,7 @@ It also offers a very useful utility of exporting org-mode buffers to different (push '("conf-unix" . conf-unix) org-src-lang-modes) (setq org-export-with-broken-links 'mark) + (setq org-confirm-babel-evaluate nil) #+end_src diff --git a/index.html b/index.html index f2605a6..2d5728d 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + SwarselSystems: NixOS + Emacs Configuration @@ -222,8 +222,8 @@
  • 2.3.3. General (outputs)
  • 2.3.4. nixosConfigurations
  • 2.3.5. homeConfigurations
  • -
  • 2.3.6. nixOnDroidConfigurations
  • -
  • 2.3.7. nixos-generators
  • +
  • 2.3.6. darwinConfigurations
  • +
  • 2.3.7. nixOnDroidConfigurations
  • @@ -246,7 +246,8 @@
  • 3.3. NixOS
  • 3.4. Home-manager @@ -285,63 +286,69 @@
  • 4.3.1. General setup
  • 4.3.2. Mark all themes as safe
  • 4.3.3. Show less compilation warnings
  • -
  • 4.3.4. Indentation
  • -
  • 4.3.5. Scrolling
  • -
  • 4.3.6. Evil
  • -
  • 4.3.7. ispell
  • -
  • 4.3.8. Font Configuration
  • -
  • 4.3.9. Theme
  • -
  • 4.3.10. Icons
  • -
  • 4.3.11. Variable Pitch Mode
  • -
  • 4.3.12. Modeline
  • -
  • 4.3.13. Helper Modes
  • -
  • 4.3.14. Ligatures
  • -
  • 4.3.15. Popup (popper) + Shackle Buffers
  • -
  • 4.3.16. Indicate first and last line of buffer
  • -
  • 4.3.17. Authentication
  • +
  • 4.3.4. Better garbage collection
  • +
  • 4.3.5. Indentation
  • +
  • 4.3.6. Scrolling
  • +
  • 4.3.7. Evil
  • +
  • 4.3.8. ispell
  • +
  • 4.3.9. Font Configuration
  • +
  • 4.3.10. Theme
  • +
  • 4.3.11. Icons
  • +
  • 4.3.12. Variable Pitch Mode
  • +
  • 4.3.13. Modeline
  • +
  • 4.3.14. Helper Modes
  • +
  • 4.3.15. Ligatures
  • +
  • 4.3.16. Popup (popper) + Shackle Buffers
  • +
  • 4.3.17. Indicate first and last line of buffer
  • +
  • 4.3.18. Authentication
  • 4.4. Modules
  • @@ -350,7 +357,7 @@

    -This file has 45632 words spanning 12064 lines and was last revised on 2024-08-31 18:00:48 +0200. +This file has 50557 words spanning 13534 lines and was last revised on 2024-12-03 18:58:56 +0100.

    @@ -400,7 +407,7 @@ This section defines my Emacs configuration. For a while, I considered to use ry

    -My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2024-08-31 18:00:48 +0200) +My emacs is built using the emacs-overlay nix flake, which builds a bleeding edge emacs on wayland (pgtk) with utilities like treesitter support. By executing the below source block, the current build setting can be updated at any time, and you can see my most up-to-date build options (last updated: 2024-12-03 18:58:56 +0100)

    @@ -412,7 +419,7 @@ system-configuration-options
    ---prefix=/nix/store/bjzr50zcpb5dqwybljizsvzs7pzx3jk5-emacs-pgtk-20240827.0 --disable-build-details --with-modules --with-pgtk --with-compress-install --with-toolkit-scroll-bars --with-native-compilation --without-imagemagick --with-mailutils --without-small-ja-dic --with-tree-sitter --without-xinput2 --with-xwidgets --with-dbus --with-selinux
    +--prefix=/nix/store/b9fzqsndbrp844c1c6mkwd6qg6l6nnj3-emacs-pgtk-20241013.0 --disable-build-details --with-modules --with-pgtk --with-compress-install --with-toolkit-scroll-bars --with-native-compilation --without-imagemagick --with-mailutils --without-small-ja-dic --with-tree-sitter --without-xinput2 --without-xwidgets --with-dbus --with-selinux
     
    @@ -548,6 +555,7 @@ fonts = {

    At work I am using several services that are using SSO login - however, as I am using four different accounts at work, this becomes a chore here. Hence, I have defined multiple profiles in Work that are all practically using the same configuration. To save screen space, I template that profile here. +Set in firefox `about:config > toolkit.legacyUserProfileCustomizations.stylesheets` to true.

    @@ -751,7 +759,7 @@ Handling the flake.nix file used to be a bit of a chore, since it felt like writ

    -These blocks are later inserted here: flake.nix template. Adding new flake inputs is very easy, you just add them to Inputs & Inputs@Outputs first by name in the first source-block, and then the path in the second source-block. Any variables to be set for the host configuration are done in let, and the specific setup is done in either nixosConfigurations (for NixOS systems), homeConfigurations (for home-manager systems), or nixOnDroidConfigurations (for Nix on Android). There is also the nixos-generators section that currently just defines a Proxmox LXC image. +These blocks are later inserted here: flake.nix template. Adding new flake inputs is very easy, you just add them to Inputs & Inputs@Outputs first by name in the first source-block, and then the path in the second source-block. Any variables to be set for the host configuration are done in let, and the specific setup is done in either nixosConfigurations (for NixOS systems), homeConfigurations (for home-manager systems), or nixOnDroidConfigurations (for Nix on Android). There is also the [BROKEN LINK: h:6a08495a-8566-4bb5-9fac-b03df01f6c81] section that currently just defines a Proxmox LXC image.

    @@ -847,7 +855,7 @@ lanzaboote.url = "github:nix-community/lanzaboote"; # nix for android nix-on-droid = { - url = "github:t184256/nix-on-droid/release-23.05"; + url = "github:nix-community/nix-on-droid/release-24.05"; inputs.nixpkgs.follows = "nixpkgs"; }; @@ -885,6 +893,20 @@ disko = { impermanence.url = "github:nix-community/impermanence"; +zjstatus = { + url = "github:dj95/zjstatus"; +}; + +fw-fanctrl = { + url = "github:TamtamHero/fw-fanctrl/packaging/nix"; + inputs.nixpkgs.follows = "nixpkgs"; +}; + +nix-darwin = { + url = "github:lnl7/nix-darwin"; + inputs.nixpkgs.follows = "nixpkgs"; +}; +
    @@ -982,6 +1004,7 @@ overlays = [ (import ./overlays { inherit inputs; }).additions (import ./overlays { inherit inputs; }).modifications (import ./overlays { inherit inputs; }).nixpkgs-stable + (import ./overlays { inherit inputs; }).zjstatus inputs.nur.overlay inputs.emacs-overlay.overlay inputs.nixgl.overlay @@ -1001,124 +1024,77 @@ This section used to be much longer, since I performed all of my imports right h
     
    -  sandbox = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.disko.nixosModules.disko
    -      ./profiles/sandbox/disk-config.nix
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/sandbox/nixos.nix
    -    ];
    -  };
    +live = lib.nixosSystem {
    +  specialArgs = { inherit inputs outputs; };
    +  system = "x86_64-linux";
    +  modules = nixModules ++ [
    +    (nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
    +    ./profiles/live
    +  ];
    +};
     
    -  threed = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = nixModules ++ [
    -      inputs.lanzaboote.nixosModules.lanzaboote
    -      ./profiles/threed/nixos.nix
    -      inputs.home-manager.nixosModules.home-manager
    -      {
    -        home-manager.users.swarsel.imports = mixedModules ++ [
    -          ./profiles/threed/home.nix
    -        ];
    -      }
    -    ];
    -  };
    +sandbox = nixpkgs.lib.nixosSystem {
    +  specialArgs = { inherit inputs; };
    +  modules = [
    +    inputs.disko.nixosModules.disko
    +    ./profiles/sandbox/disk-config.nix
    +    inputs.sops-nix.nixosModules.sops
    +    ./profiles/sandbox/nixos.nix
    +  ];
    +};
     
    -  fourside = lib.nixosSystem {
    -    specialArgs = { inherit inputs outputs; };
    -    modules = nixModules ++ [
    -      ./profiles/fourside
    -    ];
    -  };
    +threed = nixpkgs.lib.nixosSystem {
    +  specialArgs = { inherit inputs; };
    +  modules = nixModules ++ [
    +    inputs.lanzaboote.nixosModules.lanzaboote
    +    ./profiles/threed/nixos.nix
    +    inputs.home-manager.nixosModules.home-manager
    +    {
    +      home-manager.users.swarsel.imports = mixedModules ++ [
    +        ./profiles/threed/home.nix
    +      ];
    +    }
    +  ];
    +};
     
    -  nbl-imba-2 = lib.nixosSystem {
    -    specialArgs = { inherit inputs outputs; };
    -    modules = nixModules ++ [
    -      ./profiles/nbl-imba-2
    -    ];
    -  };
    +fourside = lib.nixosSystem {
    +  specialArgs = { inherit inputs outputs; };
    +  modules = nixModules ++ [
    +    ./profiles/fourside
    +  ];
    +};
     
    -nginx = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/nginx/nixos.nix
    -    ];
    -  };
    +nbl-imba-2 = lib.nixosSystem {
    +  specialArgs = { inherit inputs outputs; };
    +  modules = nixModules ++ [
    +    ./profiles/nbl-imba-2
    +  ];
    +};
     
    -  calibre = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/calibre/nixos.nix
    -    ];
    -  };
    +winters = lib.nixosSystem {
    +  specialArgs = { inherit inputs outputs; };
    +  modules = [
    +    ./profiles/server/winters
    +  ];
    +};
     
    -  jellyfin = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      ./profiles/server1/jellyfin/nixos.nix
    -    ];
    -  };
    +#ovm swarsel
    +sync = nixpkgs.lib.nixosSystem {
    +  specialArgs = { inherit inputs; };
    +  modules = [
    +    inputs.sops-nix.nixosModules.sops
    +    ./profiles/remote/oracle/sync/nixos.nix
    +  ];
    +};
     
    -  transmission = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/transmission/nixos.nix
    -    ];
    -  };
    -
    -  matrix = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/matrix/nixos.nix
    -    ];
    -  };
    -
    -  sound = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/sound/nixos.nix
    -    ];
    -  };
    -
    -  spotifyd = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/spotifyd/nixos.nix
    -    ];
    -  };
    -
    -  paperless = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/server1/paperless/nixos.nix
    -    ];
    -  };
    -
    -  #ovm swarsel
    -  sync = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/remote/oracle/sync/nixos.nix
    -    ];
    -  };
    -
    -  #ovm swarsel
    -  swatrix = nixpkgs.lib.nixosSystem {
    -    specialArgs = { inherit inputs; };
    -    modules = [
    -      inputs.sops-nix.nixosModules.sops
    -      ./profiles/remote/oracle/matrix/nixos.nix
    -    ];
    -  };
    +#ovm swarsel
    +swatrix = nixpkgs.lib.nixosSystem {
    +  specialArgs = { inherit inputs; };
    +  modules = [
    +    inputs.sops-nix.nixosModules.sops
    +    ./profiles/remote/oracle/matrix/nixos.nix
    +  ];
    +};
     
    @@ -1144,18 +1120,19 @@ In contrast, this defines home-manager systems, which I only have one of, that s -
    -

    2.3.6. nixOnDroidConfigurations

    -
    +
    +

    2.3.6. darwinConfigurations

    +

    -Nix on Android also demands an own flake output, which is provided here. +In contrast, this defines home-manager systems, which I only have one of, that serves as a template mostly.

    -default = inputs.nix-on-droid.lib.nixOnDroidConfiguration {
    +"nbm-imba-166" = inputs.nix-darwin.lib.darwinSystem {
    + specialArgs = { inherit inputs outputs; };
       modules = [
    -    ./profiles/mysticant/configuration.nix
    +    ./profiles/nbm-imba-166
       ];
     };
     
    @@ -1163,36 +1140,20 @@ default = inputs.nix-on-droid.lib.nixOnDroidConfiguration {
     
    -
    -

    2.3.7. nixos-generators

    -
    +
    +

    2.3.7. nixOnDroidConfigurations

    +

    -This builds my Proxmox template. It is defined as a separate output so that I can already apply some rudimentary configuration before even setting up the system. -

    - -

    -Usage: -

    - -
    -
    -nix build ~/.dotfiles/#proxmox-lxc
    -
    -
    -
    - -

    -The resulting image can then be loaded in Proxmox. +Nix on Android also demands an own flake output, which is provided here.

    -proxmox-lxc = inputs.nixos-generators.nixosGenerate {
    -  inherit system;
    +mysticant = inputs.nix-on-droid.lib.nixOnDroidConfiguration {
    + pkgs = pkgsFor.aarch64-linux;
       modules = [
    -     ./profiles/server1/TEMPLATE/nixos.nix
    +    ./profiles/mysticant
       ];
    -  format = "proxmox-lxc";
     };
     
     
    @@ -1211,16 +1172,97 @@ proxmox-lxc = inputs.nixos-generators.nixosGenerate {

    This section mainly exists house different `configuration.nix` files for system level configurations of NixOS systems as well as `home.nix` for user level configurations on all systems.

    - -

    -Important: Think about if a settings really needs to go into this area - chances are that the settings can also go to the general settings, which is to be preferred in order to reduce code duplication. -

    3.1.1. Physical hosts

      +
    1. live (ISO)
      +
      +
      +
      { inputs, outputs, config, pkgs, lib, ... }:
      +{
      +
      +  imports = [
      +
      +    # ../optional/nixos/steam.nix
      +    # ../optional/nixos/virtualbox.nix
      +    # ../optional/nixos/vmware.nix
      +    ../optional/nixos/autologin.nix
      +    ../optional/nixos/nswitch-rcm.nix
      +    # ../optional/nixos/work.nix
      +
      +    inputs.home-manager.nixosModules.home-manager
      +    {
      +      home-manager.users.swarsel.imports = outputs.mixedModules ++ [
      +        ../optional/home/gaming.nix
      +        # ../optional/home/work.nix
      +      ] ++ (builtins.attrValues outputs.homeManagerModules);
      +    }
      +  ] ++ (builtins.attrValues outputs.nixosModules);
      +
      +
      +  nixpkgs = {
      +    inherit (outputs) overlays;
      +    config = {
      +      allowUnfree = true;
      +      allowBroken = true;
      +    };
      +  };
      +
      +  isoImage.makeEfiBootable = true;
      +  isoImage.makeUsbBootable = true;
      +
      +  networking.networkmanager.wifi.scanRandMacAddress = false;
      +
      +  boot = {
      +    loader.efi.canTouchEfiVariables = true;
      +    kernelPackages = pkgs.linuxPackages_latest;
      +  };
      +
      +  system.stateVersion = lib.mkForce "23.05";
      +  services.getty.autologinUser = lib.mkForce "swarsel";
      +
      +  networking = {
      +    hostName = "live";
      +    wireless.enable = lib.mkForce false;
      +    firewall.enable = true;
      +  };
      +
      +
      +  swarselsystems = {
      +    wallpaper = ../../wallpaper/lenovowp.png;
      +    hasBluetooth = true;
      +    hasFingerprint = true;
      +    impermanence = false;
      +    initialSetup = true;
      +    isBtrfs = false;
      +  };
      +
      +  home-manager.users.swarsel.swarselsystems = {
      +    isLaptop = false;
      +    isNixos = true;
      +    isBtrfs = false;
      +    startup = [
      +      { command = "nextcloud --background"; }
      +      { command = "vesktop --start-minimized --enable-speech-dispatcher --ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime"; }
      +      { command = "element-desktop --hidden  --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; }
      +      { command = "ANKI_WAYLAND=1 anki"; }
      +      { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; }
      +      { command = "nm-applet"; }
      +      { command = "teams-for-linux"; }
      +      { command = "1password"; }
      +      { command = "feishin"; }
      +    ];
      +  };
      +}
      +
      +
      +
      +
      +
      +
    2. Home-manager only

      @@ -2262,12 +2304,14 @@ My work machine. Built for more security, this is the gold standard of my config imports = [ inputs.nixos-hardware.nixosModules.framework-16-7040-amd + inputs.fw-fanctrl.nixosModules.default ./hardware-configuration.nix ./disk-config.nix ../optional/nixos/steam.nix - # ../optional/nixos/virtualbox.nix + ../optional/nixos/virtualbox.nix + # ../optional/nixos/vmware.nix ../optional/nixos/autologin.nix ../optional/nixos/nswitch-rcm.nix ../optional/nixos/work.nix @@ -2306,6 +2350,17 @@ My work machine. Built for more security, this is the gold standard of my config resumeDevice = "/dev/disk/by-label/nixos"; }; + hardware = { + amdgpu = { + opencl.enable = true; + amdvlk = { + enable = true; + support32Bit.enable = true; + }; + }; + }; + + programs.fw-fanctrl.enable = true; networking = { hostName = "nbl-imba-2"; @@ -2342,22 +2397,24 @@ My work machine. Built for more security, this is the gold standard of my config # | DP-4 | |eDP-1| # ------ ----- startup = [ - { command = "nextcloud --background"; } - { command = "vesktop --start-minimized --enable-speech-dispatcher --ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime"; } - { command = "element-desktop --hidden --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } - { command = "ANKI_WAYLAND=1 anki"; } - { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } - { command = "nm-applet"; } - { command = "teams-for-linux"; } - { command = "1password"; } - ]; + { command = "nextcloud --background"; } + { command = "vesktop --start-minimized --enable-speech-dispatcher --ozone-platform-hint=auto --enable-features=WaylandWindowDecorations --enable-wayland-ime"; } + { command = "element-desktop --hidden --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu-driver-bug-workarounds"; } + { command = "ANKI_WAYLAND=1 anki"; } + { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } + { command = "nm-applet"; } + { command = "teams-for-linux"; } + { command = "1password"; } + { command = "feishin"; } + ]; + sharescreen = "eDP-2"; monitors = { main = { name = "BOE 0x0BC9 Unknown"; mode = "2560x1600"; # TEMPLATE scale = "1"; position = "2560,0"; - workspace = "10:十"; + workspace = "15:L"; output = "eDP-2"; }; homedesktop = { @@ -2397,7 +2454,7 @@ My work machine. Built for more security, this is the gold standard of my config mode = "3840x2160"; scale = "1"; position = "-1280,0"; - workspace = "1:一"; + workspace = "11:M"; output = "DP-8"; }; work_middle_middle_side = { @@ -2409,6 +2466,14 @@ My work machine. Built for more security, this is the gold standard of my config workspace = "12:S"; output = "DP-9"; }; + work_seminary = { + name = "Applied Creative Technology Transmitter QUATTRO201811"; + mode = "1280x720"; + scale = "1"; + position = "10000,10000"; # i.e. this screen is inaccessible by moving the mouse + workspace = "12:S"; + output = "DP-4"; + }; }; inputs = { "12972:18:Framework_Laptop_16_Keyboard_Module_-_ANSI_Keyboard" = { @@ -2435,12 +2500,182 @@ My work machine. Built for more security, this is the gold standard of my config }; }; keybindings = { - "Mod4+Ctrl+p" = "exec wl-mirror eDP-2"; + "Mod4+Ctrl+Shift+p" = "exec screenshare"; + }; + shellAliases = { + ans2-15_3-9 = ". ~/.venvs/ansible39_2_15_0/bin/activate"; + ans3-9 = ". ~/.venvs/ansible39/bin/activate"; + ans = ". ~/.venvs/ansible/bin/activate"; + ans2-15 = ". ~/.venvs/ansible2.15.0/bin/activate"; }; }; } + +

      +
    + +
  • Winters (Server)
    +
    +
    +
    { inputs, outputs, config, ... }:
    +{
    +
    +  imports = [
    +    inputs.sops-nix.nixosModules.sops
    +
    +    ./hardware-configuration.nix
    +
    +    ../../optional/nixos/autologin.nix
    +    ../../server/common
    +
    +  ] ++ (builtins.attrValues outputs.nixosModules);
    +
    +
    +  nixpkgs = {
    +    inherit (outputs) overlays;
    +    config = {
    +      allowUnfree = true;
    +    };
    +  };
    +
    +
    +  boot = {
    +    loader.systemd-boot.enable = true;
    +    loader.efi.canTouchEfiVariables = true;
    +  };
    +
    +  networking = {
    +    hostName = "winters";
    +    hostId = "b7778a4a";
    +    firewall.enable = true;
    +    enableIPv6 = true;
    +    firewall.allowedTCPPorts = [ 80 443 ];
    +  };
    +
    +
    +  swarselsystems = {
    +    hasBluetooth = false;
    +    hasFingerprint = false;
    +    impermanence = false;
    +    isBtrfs = false;
    +    flakePath = "/home/swarsel/.dotfiles";
    +    server = {
    +      enable = true;
    +      kavita = true;
    +      navidrome = true;
    +      jellyfin = true;
    +      spotifyd = true;
    +      mpd = false;
    +      matrix = true;
    +      nextcloud = true;
    +      immich = true;
    +      paperless = true;
    +      transmission = true;
    +      syncthing = true;
    +      monitoring = true;
    +      jenkins = false;
    +    };
    +  };
    +
    +}
    +
    +
    +
    +
    +
    +
  • +
  • nbm-imba-166 (MacBook Pro)
    +
    +
    +
    { inputs, outputs, config, pkgs, lib, ... }:
    +{
    +
    +  imports = [
    +    inputs.home-manager.darwinModules.home-manager
    +    {
    +      home-manager.useGlobalPkgs = true;
    +      home-manager.useUserPackages = true;
    +      home-manager.users."leon.schwarzaeugl".imports = [
    +      ] ++ (builtins.attrValues outputs.homeManagerModules);
    +    }
    +  ] ++ (builtins.attrValues outputs.nixosModules);
    +
    +  nix.settings.experimental-features = "nix-command flakes";
    +  nixpkgs = {
    +    hostPlatform = "x86_64-darwin";
    +    inherit (outputs) overlays;
    +    config = {
    +      allowUnfree = true;
    +    };
    +  };
    +
    +  # Auto upgrade nix package and the daemon service.
    +  services.nix-daemon.enable = true;
    +  services.karabiner-elements.enable = true;
    +
    +  home-manager.users."leon.schwarzaeugl".home.stateVersion = "23.05";
    +  home-manager.users."leon.schwarzaeugl".swarselsystems = {
    +    isDarwin = true;
    +    isLaptop = true;
    +    isNixos = false;
    +    isBtrfs = false;
    +  };
    +
    +  system.stateVersion = 4;
    +
    +}
    +
    +
    +
    +
  • +
  • Magicant (Phone)
    +
    +
    +
    +{ pkgs, ... }: {
    +  environment = {
    +    packages = with pkgs; [
    +      vim
    +      git
    +      openssh
    +      # toybox
    +      dig
    +      man
    +      gnupg
    +    ];
    +
    +    etcBackupExtension = ".bak";
    +    extraOutputsToInstall = [
    +      "doc"
    +      "info"
    +      "devdoc"
    +    ];
    +    motd = null;
    +  };
    +
    +
    +  android-integration = {
    +    termux-open.enable = true;
    +    xdg-open.enable = true;
    +    termux-open-url.enable = true;
    +    termux-reload-settings.enable = true;
    +    termux-setup-storage.enable = true;
    +  };
    +
    +  # Backup etc files instead of failing to activate generation if a file already exists in /etc
    +
    +  # Read the changelog before changing this value
    +  system.stateVersion = "23.05";
    +
    +  # Set up nix for flakes
    +  nix.extraOptions = ''
    +    experimental-features = nix-command flakes
    +  '';
    +}
    +
    +
     
    @@ -2451,399 +2686,15 @@ My work machine. Built for more security, this is the gold standard of my config

    3.1.2. Virtual hosts

    -My server setup is built on Proxmox VE; back when I started, I created all kinds of wild Debian/Ubuntu/etc. KVMs and LXCs on there. However, the root disk has suffered a weird failure where it has become unable to be cloned, but it is still functional for now. I am currently rewriting all machines on there to use NixOS instead; this is a ongoing process. +My server setup was originally built on Proxmox VE; back when I started, I created all kinds of wild Debian/Ubuntu/etc. KVMs and LXCs on there. However, the root disk has suffered a weird failure where it has become unable to be cloned, but it is still functional for now. I was for a long time rewriting all machines on there to use NixOS instead; this process is now finished.

    -In the long run, I am thinking about a transition to kubernetes or using just a server running NixOS and using the built-in container functionality. For now however, I like the network management provided by Proxmox, as I am a bit intimidated by doing that from scratch. +I have removed most of the machines from this section. What remains are some hosts that I have deployed on OCI (mostly sync for medium-important data) and one other machine that I left for now as a reference.

      -
    1. TEMPLATE
      -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { pkgs, modulesPath, ... }:
        -
        -{
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -  ];
        -
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -  ];
        -
        -  services.xserver.xkb = {
        -    layout = "us";
        -    variant = "altgr-intl";
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -  networking = {
        -    hostName = "TEMPLATE"; # Define your hostname.
        -    useDHCP = true;
        -    enableIPv6 = false;
        -    firewall.enable = false;
        -  };
        -  services.openssh = {
        -    enable = true;
        -    settings.PermitRootLogin = "yes";
        -  };
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -  # users.users.root.password = "TEMPLATE";
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -}
        -
        -
        -
        -
        -
      2. -
      -
    2. -
    3. NGINX
      -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, ... }:
        -{
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -  ];
        -
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -    lego
        -    nginx
        -  ];
        -
        -  services.xserver.xkb = {
        -    layout = "us";
        -    variant = "altgr-intl";
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/.dotfiles/secrets/nginx/secrets.yaml";
        -    validateSopsFiles = false;
        -    secrets.dnstokenfull = { owner = "acme"; };
        -    templates."certs.secret".content = ''
        -      CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull}
        -    '';
        -  };
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -  networking = {
        -    hostName = "nginx"; # Define your hostname.
        -    useDHCP = true;
        -    enableIPv6 = false;
        -    firewall.enable = false;
        -  };
        -  services.openssh = {
        -    enable = true;
        -    settings.PermitRootLogin = "yes";
        -  };
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -  # users.users.root.password = "TEMPLATE";
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  security.acme = {
        -    acceptTerms = true;
        -    preliminarySelfsigned = false;
        -    defaults.email = "mrswarsel@gmail.com";
        -    defaults.dnsProvider = "cloudflare";
        -    defaults.environmentFile = "${config.sops.templates."certs.secret".path}";
        -  };
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -  services.nginx = {
        -    enable = true;
        -    recommendedProxySettings = true;
        -    recommendedTlsSettings = true;
        -    recommendedOptimisation = true;
        -    recommendedGzipSettings = true;
        -    virtualHosts = {
        -
        -      "stash.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "https://192.168.1.5";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -          # "/push/" = {
        -          # proxyPass = "http://192.168.2.5:7867";
        -          # };
        -          "/.well-known/carddav" = {
        -            return = "301 $scheme://$host/remote.php/dav";
        -          };
        -          "/.well-known/caldav" = {
        -            return = "301 $scheme://$host/remote.php/dav";
        -          };
        -        };
        -      };
        -
        -      "matrix2.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "~ ^(/_matrix|/_synapse/client)" = {
        -            proxyPass = "http://192.168.1.23:8008";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -
        -      "sound.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "http://192.168.1.13:4040";
        -            proxyWebsockets = true;
        -            extraConfig = ''
        -              proxy_redirect          http:// https://;
        -              proxy_read_timeout      600s;
        -              proxy_send_timeout      600s;
        -              proxy_buffering         off;
        -              proxy_request_buffering off;
        -              client_max_body_size    0;
        -            '';
        -          };
        -        };
        -      };
        -
        -      "scan.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "http://192.168.1.24:28981";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -      "screen.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "http://192.168.1.16:8096";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -      "matrix.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "~ ^(/_matrix|/_synapse/client)" = {
        -            proxyPass = "http://192.168.1.20:8008";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -      "scroll.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "http://192.168.1.22:8080";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -      "blog.swarsel.win" = {
        -        enableACME = true;
        -        forceSSL = true;
        -        acmeRoot = null;
        -        locations = {
        -          "/" = {
        -            proxyPass = "https://192.168.1.7";
        -            extraConfig = ''
        -              client_max_body_size 0;
        -            '';
        -          };
        -        };
        -      };
        -
        -    };
        -  };
        -
        -}
        -
        -
        -
        -
        -
      2. -
      -
    4. -
    5. [Manual steps required] Calibre
      -
      -

      -This machine requires manual setup: -

      -
        -
      1. (obsolete for now) Set up calibre-web: -
          -
        • Create metadata.db with 664 permissions, make sure parent directory is writeable
        • -
        • Login @ books.swarsel.win using initial creds: -
            -
          • user: admin
          • -
          • pw: admin123
          • -
        • -
        • point to metadata.db file, make sure you can upload
        • -
        • Change pw, create normal user
        • -
      2. -
      3. Setup kavita: -
          -
        • Login @ scrolls.swarsel.win
        • -
        • Create admin user
        • -
        • Import Libraries
        • -
        • Create normal user
        • -
      4. -
      - -

      -In general, I am not amazed by this setup; Kavita is the reader of choice, calibre-web mostly is there to have a convenient way to fullfill the opinionated folder structure when uploading ebooks (calibre-web does not work on its own since it forces sqlite which does not work nicely with my NFS book store). I hope that in the future Kavita will implement ebook upload, or that calibre-web will ditch the sqlite constraints. -

      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, ... }:
        -
        -{
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -  ];
        -
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -    calibre
        -  ];
        -
        -  users.groups.lxc_shares = {
        -    gid = 10000;
        -    members = [
        -      "kavita"
        -      "calibre-web"
        -      "root"
        -    ];
        -  };
        -
        -  services.xserver.xkb = {
        -    layout = "us";
        -    variant = "altgr-intl";
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/.dotfiles/secrets/calibre/secrets.yaml";
        -    validateSopsFiles = false;
        -    secrets.kavita = { owner = "kavita"; };
        -  };
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -  networking = {
        -    hostName = "calibre"; # Define your hostname.
        -    useDHCP = true;
        -    enableIPv6 = false;
        -    firewall.enable = false;
        -  };
        -  services.openssh = {
        -    enable = true;
        -    settings.PermitRootLogin = "yes";
        -  };
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -  services.kavita = {
        -    enable = true;
        -    user = "kavita";
        -    port = 8080;
        -    tokenKeyFile = config.sops.secrets.kavita.path;
        -  };
        -
        -
        -}
        -
        -
        -
        -
        -
      2. -
      -
    6. -
    7. Jellyfin
      +
    8. Jellyfin (Local)
        @@ -2934,915 +2785,7 @@ In general, I am not amazed by this setup; Kavita is the reader of choice, calib
    9. -
    10. [WIP/Incomplete/Untested] Transmission
      -
      -

      -This stuff just does not work, I seem to be unable to create a working VPN Split Tunneling on NixOS. Maybe this is introduced by the wonky Proxmox-NixOS container interaction, I am not sure. For now, this machine does not work at all and I am stuck with my Debian Container that does this for me … -

      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, ... }:
        -
        -{
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -    # ./openvpn.nix #this file holds the vpn login data
        -  ];
        -
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -    openvpn
        -    jq
        -    iptables
        -    busybox
        -    wireguard-tools
        -  ];
        -
        -  users.groups.lxc_shares = {
        -    gid = 10000;
        -    members = [
        -      "vpn"
        -      "radarr"
        -      "sonarr"
        -      "lidarr"
        -      "readarr"
        -      "root"
        -    ];
        -  };
        -  users.groups.vpn = { };
        -
        -  users.users.vpn = {
        -    isNormalUser = true;
        -    group = "vpn";
        -    home = "/home/vpn";
        -  };
        -
        -  services.xserver.xkb = {
        -    layout = "us";
        -    variant = "altgr-intl";
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/.dotfiles/secrets/transmission/secrets.yaml";
        -    validateSopsFiles = false;
        -  };
        -
        -  boot.kernelModules = [ "tun" ];
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -  networking = {
        -    hostName = "transmission"; # Define your hostname.
        -    useDHCP = true;
        -    enableIPv6 = false;
        -    firewall.enable = false;
        -  };
        -
        -  services = {
        -    radarr = {
        -      enable = true;
        -    };
        -    readarr = {
        -      enable = true;
        -    };
        -    sonarr = {
        -      enable = true;
        -    };
        -    lidarr = {
        -      enable = true;
        -    };
        -    prowlarr = {
        -      enable = true;
        -    };
        -  };
        -
        -  networking.iproute2 = {
        -    enable = true;
        -    rttablesExtraConfig = ''
        -      200     vpn
        -    '';
        -  };
        -  environment.etc = {
        -    "openvpn/iptables.sh" =
        -      {
        -        source = ../../../scripts/server1/iptables.sh;
        -        mode = "0755";
        -      };
        -    "openvpn/update-resolv-conf" =
        -      {
        -        source = ../../../scripts/server1/update-resolv-conf;
        -        mode = "0755";
        -      };
        -    "openvpn/routing.sh" =
        -      {
        -        source = ../../../scripts/server1/routing.sh;
        -        mode = "0755";
        -      };
        -    "openvpn/ca.rsa.2048.crt" =
        -      {
        -        source = ../../../secrets/certs/ca.rsa.2048.crt;
        -        mode = "0644";
        -      };
        -    "openvpn/crl.rsa.2048.pem" =
        -      {
        -        source = ../../../secrets/certs/crl.rsa.2048.pem;
        -        mode = "0644";
        -      };
        -  };
        -  services.openssh = {
        -    enable = true;
        -    settings.PermitRootLogin = "yes";
        -    listenAddresses = [{
        -      port = 22;
        -      addr = "0.0.0.0";
        -    }];
        -  };
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -  # users.users.root.password = "TEMPLATE";
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -  sops = {
        -    templates = {
        -      "transmission-rpc" = {
        -        owner = "vpn";
        -        content = builtins.toJSON {
        -          rpc-username = config.sops.placeholder.rpcuser;
        -          rpc-password = config.sops.placeholder.rpcpass;
        -        };
        -      };
        -
        -      pia.content = ''
        -        ${config.sops.placeholder.vpnuser}
        -        ${config.sops.placeholder.vpnpass}
        -      '';
        -
        -      vpn.content = ''
        -        client
        -        dev tun
        -        proto ${config.sops.placeholder.vpnprot}
        -        remote ${config.sops.placeholder.vpnloc}
        -        resolv-retry infinite
        -        nobind
        -        persist-key
        -        persist-tun
        -        cipher aes-128-cbc
        -        auth sha1
        -        tls-client
        -        remote-cert-tls server
        -
        -        auth-user-pass ${config.sops.templates.pia.path}
        -        compress
        -        verb 1
        -        reneg-sec 0
        -
        -        crl-verify /etc/openvpn/crl.rsa.2048.pem
        -        ca /etc/openvpn/ca.rsa.2048.crt
        -
        -        disable-occ
        -        dhcp-option DNS 209.222.18.222
        -        dhcp-option DNS 209.222.18.218
        -        dhcp-option DNS 8.8.8.8
        -        route-noexec
        -      '';
        -    };
        -    secrets = {
        -      vpnuser = { };
        -      rpcuser = { owner = "vpn"; };
        -      vpnpass = { };
        -      rpcpass = { owner = "vpn"; };
        -      vpnprot = { };
        -      vpnloc = { };
        -    };
        -  };
        -  services.openvpn.servers = {
        -    pia = {
        -      autoStart = false;
        -      updateResolvConf = true;
        -      config = "config ${config.sops.templates.vpn.path}";
        -    };
        -  };
        -
        -  services.transmission = {
        -    enable = true;
        -    credentialsFile = config.sops.templates."transmission-rpc".path;
        -    user = "vpn";
        -    group = "lxc_shares";
        -    settings = {
        -
        -      alt-speed-down = 8000;
        -      alt-speed-enabled = false;
        -      alt-speed-time-begin = 0;
        -      alt-speed-time-day = 127;
        -      alt-speed-time-enabled = true;
        -      alt-speed-time-end = 360;
        -      alt-speed-up = 2000;
        -      bind-address-ipv4 = "0.0.0.0";
        -      bind-address-ipv6 = "::";
        -      blocklist-enabled = false;
        -      blocklist-url = "http://www.example.com/blocklist";
        -      cache-size-mb = 4;
        -      dht-enabled = false;
        -      download-dir = "/media/Eternor/New";
        -      download-limit = 100;
        -      download-limit-enabled = 0;
        -      download-queue-enabled = true;
        -      download-queue-size = 5;
        -      encryption = 2;
        -      idle-seeding-limit = 30;
        -      idle-seeding-limit-enabled = false;
        -      incomplete-dir = "/var/lib/transmission-daemon/Downloads";
        -      incomplete-dir-enabled = false;
        -      lpd-enabled = false;
        -      max-peers-global = 200;
        -      message-level = 1;
        -      peer-congestion-algorithm = "";
        -      peer-id-ttl-hours = 6;
        -      peer-limit-global = 100;
        -      peer-limit-per-torrent = 40;
        -      peer-port = 22371;
        -      peer-port-random-high = 65535;
        -      peer-port-random-low = 49152;
        -      peer-port-random-on-start = false;
        -      peer-socket-tos = "default";
        -      pex-enabled = false;
        -      port-forwarding-enabled = false;
        -      preallocation = 1;
        -      prefetch-enabled = true;
        -      queue-stalled-enabled = true;
        -      queue-stalled-minutes = 30;
        -      ratio-limit = 2;
        -      ratio-limit-enabled = false;
        -      rename-partial-files = true;
        -      rpc-authentication-required = true;
        -      rpc-bind-address = "0.0.0.0";
        -      rpc-enabled = true;
        -      rpc-host-whitelist = "";
        -      rpc-host-whitelist-enabled = true;
        -      rpc-port = 9091;
        -      rpc-url = "/transmission/";
        -      rpc-whitelist = "127.0.0.1,192.168.3.2";
        -      rpc-whitelist-enabled = true;
        -      scrape-paused-torrents-enabled = true;
        -      script-torrent-done-enabled = false;
        -      seed-queue-enabled = false;
        -      seed-queue-size = 10;
        -      speed-limit-down = 6000;
        -      speed-limit-down-enabled = true;
        -      speed-limit-up = 500;
        -      speed-limit-up-enabled = true;
        -      start-added-torrents = true;
        -      trash-original-torrent-files = false;
        -      umask = 2;
        -      upload-limit = 100;
        -      upload-limit-enabled = 0;
        -      upload-slots-per-torrent = 14;
        -      utp-enabled = false;
        -    };
        -  };
        -
        -
        -}
        -
        -
        -
        -
        -
      2. -
      -
    11. -
    12. [Manual steps needed] Matrix
      -
      -
        -
      1. After the initial setup, run the -
          -
        • /run/secrets-generated/matrixuserregister.sh
        • -
      2. -
      -

      -command to register a new admin user. -

      -
        -
      1. All bridges will fail on first start, copy the registration files using: -
          -
        • cp var/lib/mautrix-telegram/telegram-registration.yaml /var/lib/matrix-synapse
        • -
        • chown matrix-synapse:matrix-synapse var/lib/matrix-synapse/telegram-registration.yaml
        • -
      2. -
      -

      -Make sure to also do this for doublepuppet.yaml -

      -
        -
      1. Restart postgresql.service, matrix-synapse.service, mautrix-whatsapp.service, mautrix-telegram.service
      2. -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, sops, ... }:
        -let
        -  matrixDomain = "matrix2.swarsel.win";
        -in
        -{
        -
        -
        -  services = {
        -    xserver.xkb = {
        -      layout = "us";
        -      variant = "altgr-intl";
        -    };
        -    openssh = {
        -      enable = true;
        -      settings.PermitRootLogin = "yes";
        -      listenAddresses = [{
        -        port = 22;
        -        addr = "0.0.0.0";
        -      }];
        -    };
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -
        -  networking = {
        -    useDHCP = true;
        -    enableIPv6 = false;
        -  };
        -
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -    # we import here a service that is not available yet on normal nixpkgs
        -    # this module is hence not in the modules list, we add it ourselves
        -  ];
        -
        -  networking = {
        -    hostName = "matrix"; # Define your hostname.
        -    firewall.enable = false;
        -  };
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -    matrix-synapse
        -    lottieconverter
        -    ffmpeg
        -  ];
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/.dotfiles/secrets/matrix/secrets.yaml";
        -    validateSopsFiles = false;
        -    secrets = {
        -      matrixsharedsecret = { owner = "matrix-synapse"; };
        -      mautrixtelegram_as = { owner = "matrix-synapse"; };
        -      mautrixtelegram_hs = { owner = "matrix-synapse"; };
        -      mautrixtelegram_api_id = { owner = "matrix-synapse"; };
        -      mautrixtelegram_api_hash = { owner = "matrix-synapse"; };
        -    };
        -    templates = {
        -      "matrix_user_register.sh".content = ''
        -        register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
        -      '';
        -      matrixshared = {
        -        owner = "matrix-synapse";
        -        content = ''
        -          registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
        -        '';
        -      };
        -      mautrixtelegram = {
        -        owner = "matrix-synapse";
        -        content = ''
        -          MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
        -          MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
        -          MAUTRIX_TELEGRAM_TELEGRAM_API_ID=${config.sops.placeholder.mautrixtelegram_api_id}
        -          MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=${config.sops.placeholder.mautrixtelegram_api_hash}
        -        '';
        -      };
        -    };
        -  };
        -
        -  services.postgresql = {
        -    enable = true;
        -    initialScript = pkgs.writeText "synapse-init.sql" ''
        -      CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
        -      CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
        -        TEMPLATE template0
        -        LC_COLLATE = "C"
        -        LC_CTYPE = "C";
        -      CREATE ROLE "mautrix-telegram" WITH LOGIN PASSWORD 'telegram';
        -      CREATE DATABASE "mautrix-telegram" WITH OWNER "mautrix-telegram"
        -        TEMPLATE template0
        -        LC_COLLATE = "C"
        -        LC_CTYPE = "C";
        -      CREATE ROLE "mautrix-whatsapp" WITH LOGIN PASSWORD 'whatsapp';
        -      CREATE DATABASE "mautrix-whatsapp" WITH OWNER "mautrix-whatsapp"
        -        TEMPLATE template0
        -        LC_COLLATE = "C"
        -        LC_CTYPE = "C";
        -      CREATE ROLE "mautrix-signal" WITH LOGIN PASSWORD 'signal';
        -      CREATE DATABASE "mautrix-signal" WITH OWNER "mautrix-signal"
        -        TEMPLATE template0
        -        LC_COLLATE = "C"
        -        LC_CTYPE = "C";
        -    '';
        -  };
        -
        -  services.matrix-synapse = {
        -    enable = true;
        -    settings = {
        -      app_service_config_files = [
        -        "/var/lib/matrix-synapse/telegram-registration.yaml"
        -        "/var/lib/matrix-synapse/whatsapp-registration.yaml"
        -        "/var/lib/matrix-synapse/signal-registration.yaml"
        -        "/var/lib/matrix-synapse/doublepuppet.yaml"
        -      ];
        -      server_name = matrixDomain;
        -      public_baseurl = "https://${matrixDomain}";
        -      listeners = [
        -        {
        -          port = 8008;
        -          bind_addresses = [ "0.0.0.0" ];
        -          type = "http";
        -          tls = false;
        -          x_forwarded = true;
        -          resources = [
        -            {
        -              names = [ "client" "federation" ];
        -              compress = true;
        -            }
        -          ];
        -        }
        -      ];
        -    };
        -    extraConfigFiles = [
        -      config.sops.templates.matrixshared.path
        -    ];
        -  };
        -
        -  services.mautrix-telegram = {
        -    enable = true;
        -    environmentFile = config.sops.templates.mautrixtelegram.path;
        -    settings = {
        -      homeserver = {
        -        address = "http://localhost:8008";
        -        domain = matrixDomain;
        -      };
        -      appservice = {
        -        address = "http://localhost:29317";
        -        hostname = "0.0.0.0";
        -        port = "29317";
        -        provisioning.enabled = true;
        -        id = "telegram";
        -        # ephemeral_events = true; # not needed due to double puppeting
        -        public = {
        -          enabled = false;
        -        };
        -        database = "postgresql:///mautrix-telegram?host=/run/postgresql";
        -      };
        -      bridge = {
        -        relaybot.authless_portals = true;
        -        allow_avatar_remove = true;
        -        allow_contact_info = true;
        -        sync_channel_members = true;
        -        startup_sync = true;
        -        sync_create_limit = 0;
        -        sync_direct_chats = true;
        -        telegram_link_preview = true;
        -        permissions = {
        -          "*" = "relaybot";
        -          "@swarsel:${matrixDomain}" = "admin";
        -        };
        -        animated_sticker = {
        -          target = "gif";
        -          args = {
        -            width = 256;
        -            height = 256;
        -            fps = 30; # only for webm
        -            background = "020202"; # only for gif, transparency not supported
        -          };
        -        };
        -      };
        -    };
        -  };
        -  systemd.services.mautrix-telegram.path = with pkgs; [
        -    lottieconverter # for animated stickers conversion, unfree package
        -    ffmpeg # if converting animated stickers to webm (very slow!)
        -  ];
        -
        -  services.mautrix-whatsapp = {
        -    enable = true;
        -    settings = {
        -      homeserver = {
        -        address = "http://localhost:8008";
        -        domain = matrixDomain;
        -      };
        -      appservice = {
        -        address = "http://localhost:29318";
        -        hostname = "0.0.0.0";
        -        port = 29318;
        -        database = {
        -          type = "postgres";
        -          uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql";
        -        };
        -      };
        -      bridge = {
        -        displayname_template = "{{or .FullName .PushName .JID}} (WA)";
        -        history_sync = {
        -          backfill = true;
        -          max_initial_conversations = -1;
        -          message_count = -1;
        -          request_full_sync = true;
        -          full_sync_config = {
        -            days_limit = 900;
        -            size_mb_limit = 5000;
        -            storage_quota_mb = 5000;
        -          };
        -        };
        -        login_shared_secret_map = {
        -          matrixDomain = "as_token:doublepuppet";
        -        };
        -        sync_manual_marked_unread = true;
        -        send_presence_on_typing = true;
        -        parallel_member_sync = true;
        -        url_previews = true;
        -        caption_in_message = true;
        -        extev_polls = true;
        -        permissions = {
        -          "*" = "relaybot";
        -          "@swarsel:${matrixDomain}" = "admin";
        -        };
        -      };
        -    };
        -  };
        -
        -  services.mautrix-signal = {
        -    enable = true;
        -    settings = {
        -      homeserver = {
        -        address = "http://localhost:8008";
        -        domain = matrixDomain;
        -      };
        -      appservice = {
        -
        -        address = "http://localhost:29328";
        -        hostname = "0.0.0.0";
        -        port = 29328;
        -        database = {
        -          type = "postgres";
        -          uri = "postgresql:///mautrix-signal?host=/run/postgresql";
        -        };
        -      };
        -      bridge = {
        -        displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)";
        -        login_shared_secret_map = {
        -          matrixDomain = "as_token:doublepuppet";
        -        };
        -        caption_in_message = true;
        -        permissions = {
        -          "*" = "relaybot";
        -          "@swarsel:${matrixDomain}" = "admin";
        -        };
        -      };
        -    };
        -  };
        -
        -  # restart the bridges daily. this is done for the signal bridge mainly which stops carrying
        -  # messages out after a while.
        -
        -  systemd.timers."restart-bridges" = {
        -    wantedBy = [ "timers.target" ];
        -    timerConfig = {
        -      OnBootSec = "1d";
        -      OnUnitActiveSec = "1d";
        -      Unit = "restart-bridges.service";
        -    };
        -  };
        -
        -  systemd.services."restart-bridges" = {
        -    script = ''
        -      systemctl restart mautrix-whatsapp.service
        -      systemctl restart mautrix-signal.service
        -      systemctl restart mautrix-telegram.service
        -    '';
        -    serviceConfig = {
        -      Type = "oneshot";
        -      User = "root";
        -    };
        -  };
        -
        -}
        -
        -
        -
        -
        -
      2. -
      -
    13. -
    14. Sound
      -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, ... }:
        -
        -{
        -
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -  ];
        -
        -
        -
        -  services = {
        -    xserver.xkb = {
        -      layout = "us";
        -      variant = "altgr-intl";
        -    };
        -    openssh = {
        -      enable = true;
        -      settings.PermitRootLogin = "yes";
        -      listenAddresses = [{
        -        port = 22;
        -        addr = "0.0.0.0";
        -      }];
        -    };
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -
        -  networking = {
        -    useDHCP = true;
        -    enableIPv6 = false;
        -  };
        -
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -
        -
        -  proxmoxLXC.privileged = true; # manage hostname myself
        -
        -  users = {
        -    groups = {
        -      lxc_pshares = {
        -        gid = 110000;
        -        members = [
        -          "navidrome"
        -          "mpd"
        -          "root"
        -        ];
        -      };
        -
        -      navidrome = {
        -        gid = 61593;
        -      };
        -
        -      mpd = { };
        -    };
        -
        -    users = {
        -      navidrome = {
        -        isSystemUser = true;
        -        uid = 61593;
        -        group = "navidrome";
        -        extraGroups = [ "audio" "utmp" ];
        -      };
        -
        -      mpd = {
        -        isSystemUser = true;
        -        group = "mpd";
        -        extraGroups = [ "audio" "utmp" ];
        -      };
        -    };
        -  };
        -
        -  sound = {
        -    enable = true;
        -  };
        -
        -  hardware.enableAllFirmware = true;
        -  networking = {
        -    hostName = "sound"; # Define your hostname.
        -    firewall.enable = false;
        -  };
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -    pciutils
        -    alsa-utils
        -    mpv
        -  ];
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/.dotfiles/secrets/sound/secrets.yaml";
        -    validateSopsFiles = false;
        -    secrets.mpdpass = { owner = "mpd"; };
        -  };
        -
        -  services.navidrome = {
        -    enable = true;
        -    settings = {
        -      Address = "0.0.0.0";
        -      Port = 4040;
        -      MusicFolder = "/media";
        -      EnableSharing = true;
        -      EnableTranscodingConfig = true;
        -      Scanner.GroupAlbumReleases = true;
        -      ScanSchedule = "@every 1d";
        -      # Insert these values locally as sops-nix does not work for them
        -      LastFM.ApiKey = TEMPLATE;
        -      LastFM.Secret = TEMPLATE;
        -      Spotify.ID = TEMPLATE;
        -      Spotify.Secret = TEMPLATE;
        -      UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png";
        -      UIWelcomeMessage = "~SwarselSound~";
        -    };
        -  };
        -  services.mpd = {
        -    enable = true;
        -    musicDirectory = "/media";
        -    user = "mpd";
        -    group = "mpd";
        -    network = {
        -      port = 3254;
        -      listenAddress = "any";
        -    };
        -    credentials = [
        -      {
        -        passwordFile = config.sops.secrets.mpdpass.path;
        -        permissions = [
        -          "read"
        -          "add"
        -          "control"
        -          "admin"
        -        ];
        -      }
        -    ];
        -  };
        -}
        -
        -
        -
        -
      2. -
      -
    15. -
    16. Spotifyd
      -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { pkgs, modulesPath, ... }:
        -
        -{
        -
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -  ];
        -
        -
        -
        -  services = {
        -    xserver.xkb = {
        -      layout = "us";
        -      variant = "altgr-intl";
        -    };
        -    openssh = {
        -      enable = true;
        -      settings.PermitRootLogin = "yes";
        -      listenAddresses = [{
        -        port = 22;
        -        addr = "0.0.0.0";
        -      }];
        -    };
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -
        -  networking = {
        -    useDHCP = true;
        -    enableIPv6 = false;
        -  };
        -
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -
        -
        -  proxmoxLXC.privileged = true; # manage hostname myself
        -
        -  users.groups.spotifyd = {
        -    gid = 65136;
        -  };
        -
        -  users.users.spotifyd = {
        -    isSystemUser = true;
        -    uid = 65136;
        -    group = "spotifyd";
        -    extraGroups = [ "audio" "utmp" ];
        -  };
        -
        -  sound = {
        -    enable = true;
        -  };
        -
        -  hardware.enableAllFirmware = true;
        -  networking = {
        -    hostName = "spotifyd"; # Define your hostname.
        -    firewall.enable = false;
        -  };
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -  ];
        -
        -  services.spotifyd = {
        -    enable = true;
        -    settings = {
        -      global = {
        -        dbus_type = "session";
        -        use_mpris = false;
        -        device = "default:CARD=PCH";
        -        device_name = "SwarselSpot";
        -        mixer = "alsa";
        -        zeroconf_port = 1025;
        -      };
        -    };
        -  };
        -
        -}
        -
        -
        -
        -
        -
      2. -
      -
    17. -
    18. Sync
      +
    19. Sync (OCI)
        @@ -4020,14 +2963,14 @@ in
    20. -
    21. [Manual steps required] Swatrix
      +
    22. [Manual steps required] Swatrix (OCI)
      1. NixOS

        -The files mentioned by +This is a backup matrix server that is meant to be deployed on OCI. I have not gotten to that yet.

        @@ -4422,114 +3365,6 @@ in } - -
        -
        -
      2. -
      -
    23. -
    24. Paperless
      -
      -
      -
        -
      1. NixOS
        -
        -
        -
        { config, pkgs, modulesPath, ... }:
        -
        -{
        -
        -  imports = [
        -    (modulesPath + "/virtualisation/proxmox-lxc.nix")
        -    ./hardware-configuration.nix
        -  ];
        -
        -
        -
        -  services = {
        -    xserver.xkb = {
        -      layout = "us";
        -      variant = "altgr-intl";
        -    };
        -    openssh = {
        -      enable = true;
        -      settings.PermitRootLogin = "yes";
        -      listenAddresses = [{
        -        port = 22;
        -        addr = "0.0.0.0";
        -      }];
        -    };
        -  };
        -
        -  nix.settings.experimental-features = [ "nix-command" "flakes" ];
        -
        -  proxmoxLXC = {
        -    manageNetwork = true; # manage network myself
        -    manageHostName = false; # manage hostname myself
        -  };
        -
        -  networking = {
        -    useDHCP = true;
        -    enableIPv6 = false;
        -  };
        -
        -  users.users.root.openssh.authorizedKeys.keyFiles = [
        -    ../../../secrets/keys/authorized_keys
        -  ];
        -
        -  system.stateVersion = "23.05"; # TEMPLATE - but probably no need to change
        -
        -  environment.shellAliases = {
        -    nswitch = "cd /.dotfiles; git pull; nixos-rebuild --flake .#$(hostname) switch; cd -;";
        -  };
        -
        -
        -
        -  users.groups.lxc_shares = {
        -    gid = 10000;
        -    members = [
        -      "paperless"
        -      "root"
        -    ];
        -  };
        -
        -  environment.systemPackages = with pkgs; [
        -    git
        -    gnupg
        -    ssh-to-age
        -  ];
        -
        -  networking = {
        -    hostName = "paperless"; # Define your hostname.
        -    firewall.enable = false;
        -  };
        -
        -  sops = {
        -    age.sshKeyPaths = [ "/etc/ssh/sops" ];
        -    defaultSopsFile = "/root/.dotfiles/secrets/paperless/secrets.yaml";
        -    validateSopsFiles = false;
        -    secrets.admin = { owner = "paperless"; };
        -  };
        -
        -  services.paperless = {
        -    enable = true;
        -    mediaDir = "/media";
        -    user = "paperless";
        -    port = 28981;
        -    passwordFile = config.sops.secrets.admin.path;
        -    address = "0.0.0.0";
        -    extraConfig = {
        -      PAPERLESS_OCR_LANGUAGE = "deu+eng";
        -      PAPERLESS_URL = "scan.swarsel.win";
        -      PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
        -        optimize = 1;
        -        pdfa_image_compression = "lossless";
        -      };
        -    };
        -  };
        -
        -}
        -
         
        @@ -4585,6 +3420,7 @@ in fs-diff = callPackage ./fs-diff { }; update-checker = callPackage ./update-checker { }; github-notifications = callPackage ./github-notifications { }; + screenshare = callPackage ./screenshare { }; } @@ -4942,7 +3778,7 @@ fi
  • -
    { writeShellApplication, kitty, element-desktop-wayland, vesktop, spotify-player, sway, jq }:
    +
    { writeShellApplication, kitty, element-desktop-wayland, vesktop, spotify-player, jq }:
     
     writeShellApplication {
       name = "swarselcheck";
    @@ -5060,7 +3896,7 @@ done
     
    -
    { writeShellApplication, sway }:
    +
    { writeShellApplication }:
     
     writeShellApplication {
       name = "fs-diff";
    @@ -5123,17 +3959,48 @@ writeShellApplication {
       name = "github-notifications";
       runtimeInputs = [ jq ];
       text = ''
    -       count=$(curl -u Swarsel:"$(cat /run/user/1000/secrets/github_notif)" https://api.github.com/notifications | jq '. | length')
    +    count=$(curl -u Swarsel:"$(cat /run/user/1000/secrets/github_notif)" https://api.github.com/notifications | jq '. | length')
     
    -       if [[ "$count" != "0" ]]; then
    -           echo "{\"text\":\"$count\"}"
    -       fi
    +    if [[ "$count" != "0" ]]; then
    +        echo "{\"text\":\"$count\"}"
    +    fi
       '';
     }
     
    +
  • screenshare
    +
    +
    +
    +SHARESCREEN="$(nix eval --raw ~/.dotfiles#nixosConfigurations."$(hostname)".config.home-manager.users."$(whoami)".swarselsystems.sharescreen)"
    +
    +if [[ "$1" == "start" ]]; then
    +    wl-mirror "$SHARESCREEN" & sleep 0.1
    +    swaymsg output eDP-2 mode 1280x800
    +    swaymsg '[app_id=at.yrlf.wl_mirror] move to workspace 12:S'
    +    swaymsg '[app_id=at.yrlf.wl_mirror] fullscreen'
    +else
    +    swaymsg output eDP-2 mode 2560x1600
    +fi
    +
    +
    +
    + + +
    +
    { writeShellApplication, sway }:
    +
    +writeShellApplication {
    +  name = "screenshare";
    +  runtimeInputs = [ sway ];
    +  text = builtins.readFile ../../scripts/screenshare.sh;
    +}
    +
    +
    +
    +
  • @@ -5146,7 +4013,7 @@ This file now holds all of the "nixpkgs-changes" that I am using across the conf
    { inputs, ... }: {
       additions = final: _prev: import ../pkgs { pkgs = final; };
    -  modifications = final: _prev: {
    +  modifications = _: _prev: {
         vesktop = _prev.vesktop.override {
           withSystemVencord = true;
         };
    @@ -5163,11 +4030,11 @@ This file now holds all of the "nixpkgs-changes" that I am using across the conf
           ];
         };
     
    -    prismlauncher = _prev.prismlauncher.override {
    -      glfw = _prev.glfw-wayland-minecraft;
    -    };
    +    # prismlauncher = _prev.prismlauncher.override {
    +    #   glfw = _prev.glfw-wayland-minecraft;
    +    # };
     
    -    # river = prev.river.overrideAttrs (oldAttrs: rec {
    +    # #river = prev.river.overrideAttrs (oldAttrs: rec {
         #   pname = "river";
         #   version = "git";
         #   src = prev.fetchFromGitHub {
    @@ -5181,8 +4048,16 @@ This file now holds all of the "nixpkgs-changes" that I am using across the conf
       };
     
       nixpkgs-stable = final: _prev: {
    -    stable = import inputs.nixpkgs-stable { inherit (final) system; };
    +    stable = import inputs.nixpkgs-stable {
    +      inherit (final) system;
    +      config.allowUnfree = true;
    +    };
       };
    +
    +  zjstatus = _: _prev: {
    +    zjstatus = inputs.zjstatus.packages.${_prev.system}.default;
    +  };
    +
     }
     
     
    @@ -5210,6 +4085,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a setup = import ./setup.nix; impermanence = import ./impermanence.nix; filesystem = import ./filesystem.nix; + input = import ./input.nix; }
    @@ -5265,9 +4141,48 @@ I usually use mutableUsers = false in my NixOS configuration. Howev
    { lib, ... }:
    +let
    +  inherit (lib) mkOption types;
    +in
     
     {
    +  options.swarselsystems.flakePath = mkOption {
    +    type = types.str;
    +    default = "";
    +  };
       options.swarselsystems.initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
    +  options.swarselsystems.server.enable = lib.mkEnableOption "is a server machine";
    +  options.swarselsystems.server.kavita = lib.mkEnableOption "enable kavita on server";
    +  options.swarselsystems.server.jellyfin = lib.mkEnableOption "enable jellyfin on server";
    +  options.swarselsystems.server.navidrome = lib.mkEnableOption "enable navidrome on server";
    +  options.swarselsystems.server.spotifyd = lib.mkEnableOption "enable spotifyd on server";
    +  options.swarselsystems.server.mpd = lib.mkEnableOption "enable mpd on server";
    +  options.swarselsystems.server.matrix = lib.mkEnableOption "enable matrix on server";
    +  options.swarselsystems.server.nextcloud = lib.mkEnableOption "enable nextcloud on server";
    +  options.swarselsystems.server.immich = lib.mkEnableOption "enable immich on server";
    +  options.swarselsystems.server.paperless = lib.mkEnableOption "enable paperless on server";
    +  options.swarselsystems.server.transmission = lib.mkEnableOption "enable transmission and friends on server";
    +  options.swarselsystems.server.syncthing = lib.mkEnableOption "enable syncthing on server";
    +  options.swarselsystems.server.restic = lib.mkEnableOption "enable restic backups on server";
    +  options.swarselsystems.server.monitoring = lib.mkEnableOption "enable monitoring on server";
    +  options.swarselsystems.server.jenkins = lib.mkEnableOption "enable jenkins on server";
    +}
    +
    +
    +
    + +
  • Input
    +
    +
    +
    { lib, ... }:
    +let
    +  inherit (lib) mkOption types;
    +in
    +{
    +  options.swarselsystems.shellAliases = mkOption {
    +    type = types.attrsOf types.str;
    +    default = { };
    +  };
     }
     
    @@ -5320,6 +4235,7 @@ This holds modules that are to be used on most hosts. These are also the most im monitors = import ./monitors.nix; input = import ./input.nix; nixos = import ./nixos.nix; + darwin = import ./darwin.nix; waybar = import ./waybar.nix; startup = import ./startup.nix; wallpaper = import ./wallpaper.nix; @@ -5462,6 +4378,10 @@ in type = types.attrsOf (types.attrsOf types.str); default = { }; }; + options.swarselsystems.sharescreen = mkOption { + type = types.str; + default = ""; + }; }
    @@ -5490,6 +4410,10 @@ in xkb_layout = "us"; xkb_variant = "altgr-intl"; }; + "7504:24926:Kyria_Keyboard" = { + xkb_layout = "us"; + xkb_variant = "altgr-intl"; + }; }; }; options.swarselsystems.touchpad = mkOption { @@ -5505,7 +4429,10 @@ in type = types.attrsOf types.str; default = { }; }; - + options.swarselsystems.shellAliases = mkOption { + type = types.attrsOf types.str; + default = { }; + }; }
  • @@ -5552,6 +4479,17 @@ These are some extra options that will be used if the machine also runs NixOS. F
    +
  • darwin
    +
    +
    +
    { lib, config, ... }:
    +{
    +  options.swarselsystems.isDarwin = lib.mkEnableOption "darwin host";
    +}
    +
    +
    +
    +
  • System startup

    @@ -5590,6 +4528,7 @@ in { command = "ANKI_WAYLAND=1 anki"; } { command = "OBSIDIAN_USE_WAYLAND=1 obsidian"; } { command = "nm-applet"; } + { command = "feishin"; } ]; }; } @@ -5708,6 +4647,8 @@ Also, the system state version is set here. No need to touch it. ./xdg-portal.nix # ./yubikey-touch-detector.nix ./safeeyes.nix + ./distrobox.nix + ./lid.nix ]; nix = @@ -5776,13 +4717,15 @@ This ensures that all user-configuration happens here in the config file.

    { pkgs, config, lib, ... }:
     {
    +  sops.secrets.swarseluser = { neededForUsers = true; };
    +
       users = {
         mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;
         users.swarsel = {
           isNormalUser = true;
           description = "Leon S";
           hashedPasswordFile = lib.mkIf (!config.swarselsystems.initialSetup) config.sops.secrets.swarseluser.path;
    -      extraGroups = [ "networkmanager" "root" "docker""wheel" "lp" "audio" "video" "vboxusers" "scanner" ];
    +      extraGroups = [ "networkmanager" "docker" "wheel" "lp" "audio" "video" "vboxusers" "scanner" ];
           packages = with pkgs; [ ];
         };
       };
    @@ -5910,11 +4853,13 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
     {
     
       hardware = {
    +    # opengl.driSupport32Bit = true is replaced with graphics.enable32Bit and hence redundant
         graphics = {
           enable = true;
           enable32Bit = true;
         };
     
    +
         trackpoint = lib.mkIf config.swarselsystems.trackpoint.isAvailable {
           enable = true;
           inherit (config.swarselsystems.trackpoint) device;
    @@ -5923,7 +4868,6 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
         keyboard.qmk.enable = true;
     
     
    -
         pulseaudio = {
           enable = lib.mkIf (!config.services.pipewire.enable) true;
           package = pkgs.pulseaudioFull;
    @@ -5933,6 +4877,7 @@ Enable OpenGL, Sound, Bluetooth and various drivers.
     
         bluetooth = lib.mkIf config.swarselsystems.hasBluetooth {
           enable = true;
    +      package = pkgs.stable.bluez;
           powerOnBoot = true;
           settings = {
             General = {
    @@ -5963,6 +4908,7 @@ Pipewire handles communication on Wayland. This enables several sound tools as w
         pulse.enable = true;
         jack.enable = true;
         audio.enable = true;
    +    wireplumber.enable = true;
         alsa = {
           enable = true;
           support32Bit = true;
    @@ -5988,7 +4934,13 @@ Here I only enable networkmanager. Most of the 'real' network confi
         firewall = {
           checkReversePath = lib.mkDefault false;
           enable = lib.mkDefault true;
    -      allowedUDPPorts = [ 51820 ]; # 34197: factorio; 4380 27036 14242: barotrauma; 51820: wireguard
    +      allowedUDPPorts = [ 51820 ]; # 51820: wireguard
    +      allowedTCPPortRanges = [
    +        { from = 1714; to = 1764; } # kde-connect
    +      ];
    +      allowedUDPPortRanges = [
    +        { from = 1714; to = 1764; } # kde-connect
    +      ];
         };
     
         networkmanager = {
    @@ -6133,6 +5085,29 @@ Here I only enable networkmanager. Most of the 'real' network confi
                 };
               };
     
    +          wireguardvpn = {
    +            connection = {
    +              id = "HomeVPN";
    +              type = "wireguard";
    +              autoconnect = "false";
    +              interface-name = "wg1";
    +            };
    +            wireguard = { private-key = "$WIREGUARDPRIV"; };
    +            "wireguard-peer.$WIREGUARDPUB" = {
    +              endpoint = "$WIREGUARDENDPOINT";
    +              allowed-ips = "0.0.0.0/0";
    +            };
    +            ipv4 = {
    +              method = "ignore";
    +              address1 = "192.168.3.3/32";
    +            };
    +            ipv6 = {
    +              addr-gen-mode = "stable-privacy";
    +              method = "ignore";
    +            };
    +            proxy = { };
    +          };
    +
               "sweden-aes-128-cbc-udp-dns" = {
                 connection = {
                   autoconnect = "false";
    @@ -6264,7 +5239,6 @@ in
         validateSopsFiles = false;
     
         secrets = {
    -      swarseluser = { neededForUsers = true; };
           ernest = { };
           frauns = { };
           hotspot = { };
    @@ -6273,6 +5247,15 @@ in
           handyhotspot = { };
           vpnuser = { };
           vpnpass = { };
    +      wireguardpriv = { };
    +      wireguardpub = { };
    +      wireguardendpoint = { };
    +      stashuser = { };
    +      stashpass = { };
    +      githubforgeuser = { };
    +      githubforgepass = { };
    +      gitlabforgeuser = { };
    +      gitlabforgepass = { };
         };
         templates = {
           "network-manager.env".content = ''
    @@ -6284,7 +5267,19 @@ in
             HANDYHOTSPOT=${config.sops.placeholder.handyhotspot}
             VPNUSER=${config.sops.placeholder.vpnuser}
             VPNPASS=${config.sops.placeholder.vpnpass}
    +        WIREGUARDPRIV=${config.sops.placeholder.wireguardpriv}
    +        WIREGUARDPUB=${config.sops.placeholder.wireguardpub}
    +        WIREGUARDENDPOINT=${config.sops.placeholder.wireguardendpoint}
           '';
    +      ".authinfo" = {
    +        owner = "swarsel";
    +        path = "${config.users.users.swarsel.home}/.emacs.d/.authinfo";
    +        content = ''
    +          machine stash.swarsel.win:443 port https login ${config.sops.placeholder.stashuser} password ${config.sops.placeholder.stashpass}
    +          machine gitlab.com/api/v4 login ${config.sops.placeholder.githubforgeuser} password ${config.sops.placeholder.githubforgepass}
    +          machine api.github.com login ${config.sops.placeholder.gitlabforgeuser} password ${config.sops.placeholder.gitlabforgepass}
    +        '';
    +      };
         };
       };
     }
    @@ -6438,7 +5433,10 @@ Mostly used to install some compilers and lsp's that I want to have available wh
         # + cuda
         cudatoolkit
         # ansible
    +    ansible_2_15
    +    ansible-lint
         ansible-language-server
    +    molecule
         #lsp-bridge / python
         gcc
         gdb
    @@ -6513,8 +5511,7 @@ Do not touch this.
     
  • syncthing
    -
    -_:
    +
    _:
     {
       services.syncthing = {
         enable = true;
    @@ -6525,34 +5522,37 @@ _:
         settings = {
           devices = {
             "magicant" = {
    +          id = "VMWGEE2-4HDS2QO-KNQOVGN-LXLX6LA-666E4EK-ZBRYRRO-XFEX6FB-6E3XLQO";
    +        };
    +        "zenfone9" = {
               id = "SEH2NMT-IVRQUU5-VPW2HUQ-3GQYDBF-F6H6OY6-X3DZTUZ-LCRE2DJ-QNIXIQ2";
             };
             "sync (@oracle)" = {
               id = "ETW6TST-NPK7MKZ-M4LXMHA-QUPQHDT-VTSHH5X-CR5EIN2-YU7E55F-MGT7DQB";
             };
    -        "server1" = {
    -          id = "ZXWVC4X-IIARITZ-MERZPHN-HD55Y6G-QJM2GTB-6BWYXMR-DTO3TS2-QDBREQQ";
    +        "winters" = {
    +          id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
             };
           };
           folders = {
             "Default Folder" = {
               path = "/home/swarsel/Sync";
    -          devices = [ "sync (@oracle)" "magicant" ];
    +          devices = [ "sync (@oracle)" "magicant" "zenfone9" "winters" ];
               id = "default";
             };
             "Obsidian" = {
               path = "/home/swarsel/Nextcloud/Obsidian";
    -          devices = [ "sync (@oracle)" "magicant" ];
    +          devices = [ "sync (@oracle)" "magicant" "zenfone9" "winters" ];
               id = "yjvni-9eaa7";
             };
             "Org" = {
               path = "/home/swarsel/Nextcloud/Org";
    -          devices = [ "sync (@oracle)" "magicant" ];
    +          devices = [ "sync (@oracle)" "magicant" "zenfone9" "winters" ];
               id = "a7xnl-zjj3d";
             };
             "Vpn" = {
               path = "/home/swarsel/Vpn";
    -          devices = [ "sync (@oracle)" "magicant" ];
    +          devices = [ "sync (@oracle)" "magicant" "zenfone9" "winters" ];
               id = "hgp9s-fyq3p";
             };
           };
    @@ -6582,6 +5582,7 @@ Enables the blueman service including the nice system tray icon.
     
    _:
     {
       services.blueman.enable = true;
    +  services.hardware.bolt.enable = true;
     }
     
    @@ -6911,6 +5912,7 @@ When a program does not work, start with nix-ldd <program>. T pixman speex stdenv.cc.cc + steamPackages.steam-fhsenv-without-steam systemd tbb vulkan-loader @@ -7164,10 +6166,1576 @@ A friend of mine used this service and I used to make fun of him. But I have to
  • +
  • Podmam (distrobox)
    +
    +

    +I am using distrobox to quickly circumvent isses that I cannot immediately solve on NixOS. It is always the goal to quickly get things working on NixOS, but this prevents me from getting completely stuck. +

    + +
    +
    { pkgs, ... }:
    +{
    +  environment.systemPackages = with pkgs; [
    +    distrobox
    +    boxbuddy
    +  ];
    +
    +  virtualisation.podman = {
    +    enable = true;
    +  };
    +
    +}
    +
    +
    +
    +
  • +
  • Handle lid switch correctly
    +
    +

    +This turns off the display when the lid is closed. +

    + +
    +
    _:
    +{
    +  services.logind = {
    +    lidSwitch = "suspend";
    +    lidSwitchDocked = "ignore";
    +  };
    +  services.acpid = {
    +    enable = true;
    +    lidEventCommands =
    +      ''
    +        export PATH=$PATH:/run/current-system/sw/bin
    +        export WAYLAND_DISPLAY=wayland-1
    +        export XDG_RUNTIME_DIR=/run/user/1000
    +        export SWAYSOCK=$(ls /run/user/1000/sway-ipc.* | head -n 1)
    +
    +        LID_STATE=$(cat /proc/acpi/button/lid/*/state | grep -q closed && echo "closed" || echo "open")
    +        DOCKED=$(swaymsg -t get_outputs | grep -q 'HDMI\|DP' && echo "docked" || echo "undocked")
    +
    +        if [ "$LID_STATE" == "closed" ] && [ "$DOCKED" == "docked" ]; then
    +            swaymsg output eDP-2 disable
    +        else
    +            swaymsg output eDP-2 enable
    +        fi
    +      '';
    +  };
    +}
    +
    +
    +
    +
  • + + +
    +

    3.3.2. Server

    +
    +
    +
      +
    1. Imports, stateVersion
      +
      +

      +First, we enable the use of home-manager as a NixoS module. +

      + +

      +Also, we disable the warnings that trigger when rebuilding with a dirty flake. At this point, I am also disabling channels and pinning the flake registry - the latter lets me use the local version of nixpkgs for commands like nix shell (without it, we will always download the newest version of nixpkgs for these commands). +

      + +

      +Also, the system state version is set here. No need to touch it. +

      + +
      +
      { lib, config, inputs, ... }:
      +{
      +  imports = [
      +    ../../common/nixos/xserver.nix
      +    ../../common/nixos/gc.nix
      +    ../../common/nixos/store.nix
      +    ../../common/nixos/time.nix
      +    ../../common/nixos/pipewire.nix
      +    ../../common/nixos/users.nix
      +    ../../common/nixos/nix-ld.nix
      +    ./packages.nix
      +    ./sops.nix
      +    ./ssh.nix
      +    ./nfs.nix
      +    ./nginx.nix
      +    ./kavita.nix
      +    ./jellyfin.nix
      +    ./navidrome.nix
      +    ./spotifyd.nix
      +    ./mpd.nix
      +    ./matrix.nix
      +    ./nextcloud.nix
      +    ./immich.nix
      +    ./paperless.nix
      +    ./transmission.nix
      +    ./syncthing.nix
      +    ./restic.nix
      +    ./monitoring.nix
      +    ./jenkins.nix
      +  ];
      +
      +  nix =
      +    let
      +      flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs;
      +    in
      +    {
      +      settings = {
      +        experimental-features = [
      +          "nix-command"
      +          "flakes"
      +          "ca-derivations"
      +        ];
      +        trusted-users = [ "swarsel" ];
      +        flake-registry = "";
      +        warn-dirty = false;
      +      };
      +      channel.enable = false;
      +      registry = lib.mapAttrs (_: flake: { inherit flake; }) flakeInputs;
      +      nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
      +    };
      +
      +  environment.shellAliases = lib.recursiveUpdate
      +    {
      +      npswitch = "cd ${config.swarselsystems.flakePath}; git pull; sudo nixos-rebuild --flake .#$(hostname) switch --impure; cd -;";
      +      nswitch = "cd ${config.swarselsystems.flakePath}; sudo nixos-rebuild --flake .#$(hostname) switch --impure; cd -;";
      +    }
      +    config.swarselsystems.shellAliases;
      +
      +  nixpkgs.config.permittedInsecurePackages = [
      +    "olm-3.2.16"
      +  ];
      +
      +  system.stateVersion = lib.mkDefault "23.05";
      +}
      +
      +
      +
      +
      +
    2. +
    3. System Packages
      +
      +
      +
      { pkgs, ... }:
      +{
      +  environment.systemPackages = with pkgs; [
      +    gnupg
      +    nix-index
      +    ssh-to-age
      +    git
      +    emacs
      +  ];
      +}
      +
      +
      +
      +
    4. +
    5. sops
      +
      +
      +
      { config, ... }:
      +{
      +  sops = {
      +    age.sshKeyPaths = [ "/etc/ssh/sops" ];
      +    defaultSopsFile = "${config.swarselsystems.flakePath}/secrets/server/winters/secrets.yaml";
      +    validateSopsFiles = false;
      +  };
      +
      +}
      +
      +
      +
      +
    6. +
    7. nfs/samba (smb)
      +
      +
      +
      { pkgs, ... }:
      +{
      +  services = {
      +    # add a user with sudo smbpasswd -a <user>
      +    samba = {
      +      package = pkgs.samba4Full;
      +      # extraConfig = ''
      +      #   workgroup = WORKGROUP
      +      #   server role = standalone server
      +      #   dns proxy = no
      +
      +      #   pam password change = yes
      +      #   map to guest = bad user
      +      #   create mask = 0664
      +      #   force create mode = 0664
      +      #   directory mask = 0775
      +      #   force directory mode = 0775
      +      #   follow symlinks = yes
      +      # '';
      +
      +      enable = true;
      +      openFirewall = true;
      +      settings.Eternor = {
      +        browseable = "yes";
      +        "read only" = "no";
      +        "guest ok" = "no";
      +        path = "/Vault/Eternor";
      +        writable = "true";
      +        comment = "Eternor";
      +        "valid users" = "Swarsel";
      +      };
      +    };
      +
      +
      +    avahi = {
      +      publish.enable = true;
      +      publish.userServices = true; # Needed to allow samba to automatically register mDNS records without the need for an `extraServiceFile`
      +      nssmdns4 = true;
      +      enable = true;
      +      openFirewall = true;
      +    };
      +
      +    # This enables autodiscovery on windows since SMB1 (and thus netbios) support was discontinued
      +    samba-wsdd = {
      +      enable = true;
      +      openFirewall = true;
      +    };
      +  };
      +}
      +
      +
      +
      +
    8. +
    9. NGINX
      +
      +
      +
      { pkgs, config, ... }:
      +{
      +  environment.systemPackages = with pkgs; [
      +    lego
      +  ];
      +
      +  # users.users.acme = {};
      +
      +  sops = {
      +    # secrets.dnstokenfull = { owner = "acme"; };
      +    secrets.dnstokenfull = { };
      +    templates."certs.secret".content = ''
      +      CF_DNS_API_TOKEN=${config.sops.placeholder.dnstokenfull}
      +    '';
      +  };
      +
      +  security.acme = {
      +    acceptTerms = true;
      +    preliminarySelfsigned = false;
      +    defaults.email = "mrswarsel@gmail.com";
      +    defaults.dnsProvider = "cloudflare";
      +    defaults.environmentFile = "${config.sops.templates."certs.secret".path}";
      +  };
      +
      +  services.nginx = {
      +    enable = true;
      +    statusPage = true;
      +    recommendedProxySettings = true;
      +    recommendedTlsSettings = true;
      +    recommendedOptimisation = true;
      +    recommendedGzipSettings = true;
      +    # virtualHosts are defined in the respective sections
      +  };
      +
      +}
      +
      +
      +
      +
    10. +
    11. ssh
      +
      +
      +
      _:
      +{
      +  services.openssh = {
      +    enable = true;
      +    settings.PermitRootLogin = "yes";
      +  };
      +  users.users.swarsel.openssh.authorizedKeys.keyFiles = [
      +    ../../../secrets/keys/authorized_keys
      +    ../../../secrets/keys/mysticant.pub
      +  ];
      +  users.users.root.openssh.authorizedKeys.keyFiles = [
      +    ../../../secrets/keys/authorized_keys
      +    ../../../secrets/keys/mysticant.pub
      +  ];
      +
      +}
      +
      +
      +
      +
    12. +
    13. kavita
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.kavita {
      +    environment.systemPackages = with pkgs; [
      +      calibre
      +    ];
      +
      +
      +    users.users.jellyfin = {
      +      extraGroups = [ "users" ];
      +    };
      +
      +    sops.secrets.kavita = { owner = "kavita"; };
      +
      +    networking.firewall.allowedTCPPorts = [ 8080 ];
      +
      +    services.kavita = {
      +      enable = true;
      +      user = "kavita";
      +      settings.Port = 8080;
      +      tokenKeyFile = config.sops.secrets.kavita.path;
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "scroll.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:8080";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +}
      +
      +
      +
      +
    14. +
    15. jellyfin
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.jellyfin {
      +    users.users.jellyfin = {
      +      extraGroups = [ "video" "render" "users" ];
      +    };
      +    nixpkgs.config.packageOverrides = pkgs: {
      +      vaapiIntel = pkgs.vaapiIntel.override { enableHybridCodec = true; };
      +    };
      +    hardware.graphics = {
      +      enable = true;
      +      extraPackages = with pkgs; [
      +        intel-media-driver # LIBVA_DRIVER_NAME=iHD
      +        vaapiIntel # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
      +        vaapiVdpau
      +        libvdpau-va-gl
      +      ];
      +    };
      +    services.jellyfin = {
      +      enable = true;
      +      user = "jellyfin";
      +      openFirewall = true; # this works only for the default ports
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "screen.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:8096";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    16. +
    17. navidrome
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.navidrome {
      +    environment.systemPackages = with pkgs; [
      +      pciutils
      +      alsa-utils
      +      mpv
      +    ];
      +
      +    users = {
      +      groups = {
      +        navidrome = {
      +          gid = 61593;
      +        };
      +      };
      +
      +      users = {
      +        navidrome = {
      +          isSystemUser = true;
      +          uid = 61593;
      +          group = "navidrome";
      +          extraGroups = [ "audio" "utmp" "users" "pipewire" ];
      +        };
      +      };
      +    };
      +
      +
      +    hardware = {
      +      # opengl.enable = true;
      +      enableAllFirmware = true;
      +    };
      +
      +    networking.firewall.allowedTCPPorts = [ 4040 ];
      +
      +    services.navidrome = {
      +      enable = true;
      +      openFirewall = true;
      +      settings = {
      +        LogLevel = "error";
      +        Address = "127.0.0.1";
      +        Port = 4040;
      +        MusicFolder = "/Vault/Eternor/Musik";
      +        EnableSharing = true;
      +        EnableTranscodingConfig = true;
      +        Scanner.GroupAlbumReleases = true;
      +        ScanSchedule = "@every 24h";
      +        MPVPath = "${pkgs.mpv}/bin/mpv";
      +        MPVCommandTemplate = "mpv --audio-device=%d --no-audio-display --pause %f";
      +        Jukebox = {
      +          Enabled = true;
      +          Default = "pch";
      +          Devices = [
      +            [ "pch" "alsa/sysdefault:CARD=PCH" ]
      +          ];
      +        };
      +        # Insert these values locally as sops-nix does not work for them
      +        LastFM.ApiKey = builtins.readFile /home/swarsel/api/lastfm-secret;
      +        LastFM.Secret = builtins.readFile /home/swarsel/api/lastfm-key;
      +        Spotify.ID = builtins.readFile /home/swarsel/api/spotify-id;
      +        Spotify.Secret = builtins.readFile /home/swarsel/api/spotify-secret;
      +        UILoginBackgroundUrl = "https://i.imgur.com/OMLxi7l.png";
      +        UIWelcomeMessage = "~SwarselSound~";
      +      };
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "sound.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:4040";
      +              proxyWebsockets = true;
      +              extraConfig = ''
      +                proxy_redirect          http:// https://;
      +                proxy_read_timeout      600s;
      +                proxy_send_timeout      600s;
      +                proxy_buffering         off;
      +                proxy_request_buffering off;
      +                client_max_body_size    0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +
      +}
      +
      +
      +
      +
    18. +
    19. spotifyd
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.spotifyd {
      +    users.groups.spotifyd = {
      +      gid = 65136;
      +    };
      +
      +    users.users.spotifyd = {
      +      isSystemUser = true;
      +      uid = 65136;
      +      group = "spotifyd";
      +      extraGroups = [ "audio" "utmp" "pipewire" ];
      +    };
      +
      +    networking.firewall.allowedTCPPorts = [ 1025 ];
      +
      +    services.pipewire.systemWide = true;
      +
      +    services.spotifyd = {
      +      enable = true;
      +      settings = {
      +        global = {
      +          dbus_type = "session";
      +          use_mpris = false;
      +          device = "sysdefault:CARD=PCH";
      +          device_name = "SwarselSpot";
      +          mixer = "alsa";
      +          zeroconf_port = 1025;
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    20. +
    21. mpd
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.mpd {
      +    users = {
      +      groups = {
      +        mpd = { };
      +      };
      +
      +      users = {
      +        mpd = {
      +          isSystemUser = true;
      +          group = "mpd";
      +          extraGroups = [ "audio" "utmp" ];
      +        };
      +      };
      +    };
      +
      +    sops = {
      +      secrets.mpdpass = { owner = "mpd"; };
      +    };
      +
      +    environment.systemPackages = with pkgs; [
      +      pciutils
      +      alsa-utils
      +      mpv
      +    ];
      +
      +    services.mpd = {
      +      enable = true;
      +      musicDirectory = "/media";
      +      user = "mpd";
      +      group = "mpd";
      +      network = {
      +        port = 3254;
      +        listenAddress = "any";
      +      };
      +      credentials = [
      +        {
      +          passwordFile = config.sops.secrets.mpdpass.path;
      +          permissions = [
      +            "read"
      +            "add"
      +            "control"
      +            "admin"
      +          ];
      +        }
      +      ];
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    22. +
    23. matrix
      +
      +
      +
      { config, lib, pkgs, sops, ... }:
      +let
      +  matrixDomain = "swatrix.swarsel.win";
      +  baseUrl = "https://${matrixDomain}";
      +  clientConfig."m.homeserver".base_url = baseUrl;
      +  serverConfig."m.server" = "${matrixDomain}:443";
      +  mkWellKnown = data: ''
      +    default_type application/json;
      +    add_header Access-Control-Allow-Origin *;
      +    return 200 '${builtins.toJSON data}';
      +  '';
      +in
      +{
      +
      +  config = lib.mkIf config.swarselsystems.server.matrix {
      +    environment.systemPackages = with pkgs; [
      +      matrix-synapse
      +      lottieconverter
      +      ffmpeg
      +    ];
      +
      +    sops = {
      +      secrets = {
      +        matrixsharedsecret = { owner = "matrix-synapse"; };
      +        mautrixtelegram_as = { owner = "matrix-synapse"; };
      +        mautrixtelegram_hs = { owner = "matrix-synapse"; };
      +        mautrixtelegram_api_id = { owner = "matrix-synapse"; };
      +        mautrixtelegram_api_hash = { owner = "matrix-synapse"; };
      +      };
      +      templates = {
      +        "matrix_user_register.sh".content = ''
      +          register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008
      +        '';
      +        matrixshared = {
      +          owner = "matrix-synapse";
      +          content = ''
      +            registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
      +          '';
      +        };
      +        mautrixtelegram = {
      +          owner = "matrix-synapse";
      +          content = ''
      +            MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
      +            MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
      +            MAUTRIX_TELEGRAM_TELEGRAM_API_ID=${config.sops.placeholder.mautrixtelegram_api_id}
      +            MAUTRIX_TELEGRAM_TELEGRAM_API_HASH=${config.sops.placeholder.mautrixtelegram_api_hash}
      +          '';
      +        };
      +      };
      +    };
      +
      +    services.postgresql = {
      +      enable = true;
      +      initialScript = pkgs.writeText "synapse-init.sql" ''
      +        CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
      +        CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
      +          TEMPLATE template0
      +          LC_COLLATE = "C"
      +          LC_CTYPE = "C";
      +        CREATE ROLE "mautrix-telegram" WITH LOGIN PASSWORD 'telegram';
      +        CREATE DATABASE "mautrix-telegram" WITH OWNER "mautrix-telegram"
      +          TEMPLATE template0
      +          LC_COLLATE = "C"
      +          LC_CTYPE = "C";
      +        CREATE ROLE "mautrix-whatsapp" WITH LOGIN PASSWORD 'whatsapp';
      +        CREATE DATABASE "mautrix-whatsapp" WITH OWNER "mautrix-whatsapp"
      +          TEMPLATE template0
      +          LC_COLLATE = "C"
      +          LC_CTYPE = "C";
      +        CREATE ROLE "mautrix-signal" WITH LOGIN PASSWORD 'signal';
      +        CREATE DATABASE "mautrix-signal" WITH OWNER "mautrix-signal"
      +          TEMPLATE template0
      +          LC_COLLATE = "C"
      +          LC_CTYPE = "C";
      +      '';
      +    };
      +
      +    services.matrix-synapse = {
      +      enable = true;
      +      settings = {
      +        app_service_config_files = [
      +          "/var/lib/matrix-synapse/telegram-registration.yaml"
      +          "/var/lib/matrix-synapse/whatsapp-registration.yaml"
      +          "/var/lib/matrix-synapse/signal-registration.yaml"
      +          "/var/lib/matrix-synapse/doublepuppet.yaml"
      +        ];
      +        server_name = matrixDomain;
      +        public_baseurl = "https://${matrixDomain}";
      +        listeners = [
      +          {
      +            port = 8008;
      +            bind_addresses = [
      +              "127.0.0.1"
      +              "::1"
      +            ];
      +            type = "http";
      +            tls = false;
      +            x_forwarded = true;
      +            resources = [
      +              {
      +                names = [ "client" "federation" ];
      +                compress = true;
      +              }
      +            ];
      +          }
      +        ];
      +      };
      +      extraConfigFiles = [
      +        config.sops.templates.matrixshared.path
      +      ];
      +    };
      +
      +    services.mautrix-telegram = {
      +      enable = true;
      +      environmentFile = config.sops.templates.mautrixtelegram.path;
      +      settings = {
      +        homeserver = {
      +          address = "http://localhost:8008";
      +          domain = matrixDomain;
      +        };
      +        appservice = {
      +          address = "http://localhost:29317";
      +          hostname = "localhost";
      +          port = "29317";
      +          provisioning.enabled = true;
      +          id = "telegram";
      +          # ephemeral_events = true; # not needed due to double puppeting
      +          public = {
      +            enabled = false;
      +          };
      +          database = "postgresql:///mautrix-telegram?host=/run/postgresql";
      +        };
      +        bridge = {
      +          relaybot.authless_portals = true;
      +          allow_avatar_remove = true;
      +          allow_contact_info = true;
      +          sync_channel_members = true;
      +          startup_sync = true;
      +          sync_create_limit = 0;
      +          sync_direct_chats = true;
      +          telegram_link_preview = true;
      +          permissions = {
      +            "*" = "relaybot";
      +            "@swarsel:${matrixDomain}" = "admin";
      +          };
      +          animated_sticker = {
      +            target = "gif";
      +            args = {
      +              width = 256;
      +              height = 256;
      +              fps = 30; # only for webm
      +              background = "020202"; # only for gif, transparency not supported
      +            };
      +          };
      +        };
      +      };
      +    };
      +    systemd.services.mautrix-telegram.path = with pkgs; [
      +      lottieconverter # for animated stickers conversion, unfree package
      +      ffmpeg # if converting animated stickers to webm (very slow!)
      +    ];
      +
      +    services.mautrix-whatsapp = {
      +      enable = true;
      +      registerToSynapse = false;
      +      settings = {
      +        homeserver = {
      +          address = "http://localhost:8008";
      +          domain = matrixDomain;
      +        };
      +        appservice = {
      +          address = "http://localhost:29318";
      +          hostname = "127.0.0.1";
      +          port = 29318;
      +          database = {
      +            type = "postgres";
      +            uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql";
      +          };
      +        };
      +        bridge = {
      +          displayname_template = "{{or .FullName .PushName .JID}} (WA)";
      +          history_sync = {
      +            backfill = true;
      +            max_initial_conversations = -1;
      +            message_count = -1;
      +            request_full_sync = true;
      +            full_sync_config = {
      +              days_limit = 900;
      +              size_mb_limit = 5000;
      +              storage_quota_mb = 5000;
      +            };
      +          };
      +          login_shared_secret_map = {
      +            matrixDomain = "as_token:doublepuppet";
      +          };
      +          sync_manual_marked_unread = true;
      +          send_presence_on_typing = true;
      +          parallel_member_sync = true;
      +          url_previews = true;
      +          caption_in_message = true;
      +          extev_polls = true;
      +          permissions = {
      +            "*" = "relaybot";
      +            "@swarsel:${matrixDomain}" = "admin";
      +          };
      +        };
      +      };
      +    };
      +
      +    services.mautrix-signal = {
      +      enable = true;
      +      registerToSynapse = false;
      +      settings = {
      +        homeserver = {
      +          address = "http://localhost:8008";
      +          domain = matrixDomain;
      +        };
      +        appservice = {
      +
      +          address = "http://localhost:29328";
      +          hostname = "127.0.0.1";
      +          port = 29328;
      +          database = {
      +            type = "postgres";
      +            uri = "postgresql:///mautrix-signal?host=/run/postgresql";
      +          };
      +        };
      +        bridge = {
      +          displayname_template = "{{or .ContactName .ProfileName .PhoneNumber}} (Signal)";
      +          login_shared_secret_map = {
      +            matrixDomain = "as_token:doublepuppet";
      +          };
      +          caption_in_message = true;
      +          permissions = {
      +            "*" = "relay";
      +            "@swarsel:${matrixDomain}" = "admin";
      +          };
      +        };
      +      };
      +    };
      +
      +    # restart the bridges daily. this is done for the signal bridge mainly which stops carrying
      +    # messages out after a while.
      +
      +    systemd.timers."restart-bridges" = {
      +      wantedBy = [ "timers.target" ];
      +      timerConfig = {
      +        OnBootSec = "1d";
      +        OnUnitActiveSec = "1d";
      +        Unit = "restart-bridges.service";
      +      };
      +    };
      +
      +    systemd.services."restart-bridges" = {
      +      script = ''
      +        systemctl restart mautrix-whatsapp.service
      +        systemctl restart mautrix-signal.service
      +        systemctl restart mautrix-telegram.service
      +      '';
      +      serviceConfig = {
      +        Type = "oneshot";
      +        User = "root";
      +      };
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "swatrix.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          listen = [
      +            {
      +              addr = "0.0.0.0";
      +              port = 8448;
      +              ssl = true;
      +              extraParameters = [
      +                "default_server"
      +              ];
      +            }
      +            {
      +              addr = "[::0]";
      +              port = 8448;
      +              ssl = true;
      +              extraParameters = [
      +                "default_server"
      +              ];
      +            }
      +            {
      +              addr = "0.0.0.0";
      +              port = 443;
      +              ssl = true;
      +            }
      +            {
      +              addr = "[::0]";
      +              port = 443;
      +              ssl = true;
      +            }
      +          ];
      +          locations = {
      +            "~ ^(/_matrix|/_synapse/client)" = {
      +              # proxyPass = "http://localhost:8008";
      +              proxyPass = "http://localhost:8008";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +            "= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
      +            "= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +
      +}
      +
      +
      +
      +
      +
    24. +
    25. nextcloud
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.nextcloud {
      +
      +    sops.secrets.nextcloudadminpass = {
      +      owner = "nextcloud";
      +      group = "nextcloud";
      +      mode = "0440";
      +    };
      +
      +    services.nextcloud = {
      +      enable = true;
      +      package = pkgs.nextcloud30;
      +      hostName = "stash.swarsel.win";
      +      home = "/Vault/apps/nextcloud";
      +      datadir = "/Vault/data/nextcloud";
      +      https = true;
      +      configureRedis = true;
      +      maxUploadSize = "4G";
      +      extraApps = {
      +        inherit (pkgs.nextcloud30Packages.apps) mail calendar contacts cospend phonetrack polls tasks;
      +      };
      +      config = {
      +        adminuser = "admin";
      +        adminpassFile = config.sops.secrets.nextcloudadminpass.path;
      +      };
      +    };
      +
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "stash.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          # config is automatically added by nixos nextcloud config.
      +          # hence, only provide certificate
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    26. +
    27. immich
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.immich {
      +
      +    users.users.immich = {
      +      extraGroups = [ "video" "render" "users" ];
      +    };
      +
      +    # sops.secrets.nextcloudadminpass = { owner = "nextcloud"; };
      +
      +    services.immich = {
      +      enable = true;
      +      port = 3001;
      +      openFirewall = true;
      +      mediaLocation = "/Vault/Eternor/Immich";
      +      environment.IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003";
      +    };
      +
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "shots.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:3001";
      +              extraConfig = ''
      +                client_max_body_size    0;
      +
      +                proxy_http_version 1.1;
      +                proxy_set_header   Upgrade    $http_upgrade;
      +                proxy_set_header   Connection "upgrade";
      +                proxy_redirect     off;
      +
      +                proxy_read_timeout 600s;
      +                proxy_send_timeout 600s;
      +                send_timeout       600s;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +
      +  };
      +
      +}
      +
      +
      +
      +
    28. +
    29. paperless
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.paperless {
      +
      +    users.users.paperless = {
      +      extraGroups = [ "users" ];
      +    };
      +
      +
      +    sops.secrets.paperless_admin = { owner = "paperless"; };
      +
      +    services.paperless = {
      +      enable = true;
      +      mediaDir = "/Vault/Eternor/Paperless";
      +      dataDir = "/Vault/data/paperless";
      +      user = "paperless";
      +      port = 28981;
      +      passwordFile = config.sops.secrets.paperless_admin.path;
      +      address = "127.0.0.1";
      +      settings = {
      +        PAPERLESS_OCR_LANGUAGE = "deu+eng";
      +        PAPERLESS_URL = "https://scan.swarsel.win";
      +        PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
      +          optimize = 1;
      +          invalidate_digital_signatures = true;
      +          pdfa_image_compression = "lossless";
      +        };
      +      };
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "scan.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:28981";
      +              extraConfig = ''
      +                client_max_body_size    0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    30. +
    31. transmission
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.transmission {
      +
      +    # this user/group section is probably unneeded
      +    users = {
      +      groups = {
      +        dockeruser = {
      +          gid = 1155;
      +        };
      +        radarr = { };
      +        readarr = { };
      +        sonarr = { };
      +        lidarr = { };
      +        prowlarr = { };
      +      };
      +      users = {
      +        dockeruser = {
      +          isSystemUser = true;
      +          uid = 1155;
      +          group = "docker";
      +          extraGroups = [ "users" ];
      +        };
      +        radarr = {
      +          isSystemUser = true;
      +          group = "radarr";
      +          extraGroups = [ "users" ];
      +        };
      +        readarr = {
      +          isSystemUser = true;
      +          group = "readarr";
      +          extraGroups = [ "users" ];
      +        };
      +        sonarr = {
      +          isSystemUser = true;
      +          group = "sonarr";
      +          extraGroups = [ "users" ];
      +        };
      +        lidarr = {
      +          isSystemUser = true;
      +          group = "lidarr";
      +          extraGroups = [ "users" ];
      +        };
      +        prowlarr = {
      +          isSystemUser = true;
      +          group = "prowlarr";
      +          extraGroups = [ "users" ];
      +        };
      +      };
      +    };
      +
      +    virtualisation.docker.enable = true;
      +    environment.systemPackages = with pkgs; [
      +      docker
      +    ];
      +
      +    services = {
      +      radarr = {
      +        enable = true;
      +        openFirewall = true;
      +        dataDir = "/Vault/apps/radarr";
      +      };
      +      readarr = {
      +        enable = true;
      +        openFirewall = true;
      +        dataDir = "/Vault/apps/readarr";
      +      };
      +      sonarr = {
      +        enable = true;
      +        openFirewall = true;
      +        dataDir = "/Vault/apps/sonarr";
      +      };
      +      lidarr = {
      +        enable = true;
      +        openFirewall = true;
      +        dataDir = "/Vault/apps/lidarr";
      +      };
      +      prowlarr = {
      +        enable = true;
      +        openFirewall = true;
      +      };
      +
      +      nginx = {
      +        virtualHosts = {
      +          "store.swarsel.win" = {
      +            enableACME = false;
      +            forceSSL = false;
      +            acmeRoot = null;
      +            locations = {
      +              "/" = {
      +                proxyPass = "http://localhost:9091";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +              "/radarr" = {
      +                proxyPass = "http://localhost:7878";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +              "/readarr" = {
      +                proxyPass = "http://localhost:8787";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +              "/sonarr" = {
      +                proxyPass = "http://localhost:8989";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +              "/lidarr" = {
      +                proxyPass = "http://localhost:8686";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +              "/prowlarr" = {
      +                proxyPass = "http://localhost:9696";
      +                extraConfig = ''
      +                  client_max_body_size    0;
      +                '';
      +              };
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +}
      +
      +
      +
      +
      +
    32. +
    33. syncthing
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.syncthing {
      +
      +    users.users.syncthing = {
      +      extraGroups = [ "users" ];
      +    };
      +
      +    services.syncthing = {
      +      enable = true;
      +      user = "syncthing";
      +      dataDir = "/Vault/data/syncthing";
      +      configDir = "/Vault/apps/syncthing";
      +      guiAddress = "0.0.0.0:8384";
      +      openDefaultPorts = true;
      +      relay.enable = false;
      +      settings = {
      +        urAccepted = -1;
      +        devices = {
      +          "magicant" = {
      +            id = "VMWGEE2-4HDS2QO-KNQOVGN-LXLX6LA-666E4EK-ZBRYRRO-XFEX6FB-6E3XLQO";
      +          };
      +          "zenfone9" = {
      +            id = "SEH2NMT-IVRQUU5-VPW2HUQ-3GQYDBF-F6H6OY6-X3DZTUZ-LCRE2DJ-QNIXIQ2";
      +          };
      +          "sync (@oracle)" = {
      +            id = "ETW6TST-NPK7MKZ-M4LXMHA-QUPQHDT-VTSHH5X-CR5EIN2-YU7E55F-MGT7DQB";
      +          };
      +          "nbl-imba-2" = {
      +            id = "YAPV4BV-I26WPTN-SIP32MV-SQP5TBZ-3CHMTCI-Z3D6EP2-MNDQGLP-53FT3AB";
      +          };
      +        };
      +        folders = {
      +          "Default Folder" = {
      +            path = "/Vault/data/syncthing/Sync";
      +            type = "receiveonly";
      +            versioning = null;
      +            devices = [ "sync (@oracle)" "magicant" "zenfone9" "nbl-imba-2" ];
      +            id = "default";
      +          };
      +          "Obsidian" = {
      +            path = "/Vault/data/syncthing/Obsidian";
      +            type = "receiveonly";
      +            versioning = {
      +              type = "simple";
      +              params.keep = "5";
      +            };
      +            devices = [ "sync (@oracle)" "magicant" "zenfone9" "nbl-imba-2" ];
      +            id = "yjvni-9eaa7";
      +          };
      +          "Org" = {
      +            path = "/Vault/data/syncthing/Org";
      +            type = "receiveonly";
      +            versioning = {
      +              type = "simple";
      +              params.keep = "5";
      +            };
      +            devices = [ "sync (@oracle)" "magicant" "zenfone9" "nbl-imba-2" ];
      +            id = "a7xnl-zjj3d";
      +          };
      +          "Vpn" = {
      +            path = "/Vault/data/syncthing/Vpn";
      +            type = "receiveonly";
      +            versioning = {
      +              type = "simple";
      +              params.keep = "5";
      +            };
      +            devices = [ "sync (@oracle)" "magicant" "zenfone9" "nbl-imba-2" ];
      +            id = "hgp9s-fyq3p";
      +          };
      +          "Documents" = {
      +            path = "/Vault/data/syncthing/Documents";
      +            type = "receiveonly";
      +            versioning = {
      +              type = "simple";
      +              params.keep = "5";
      +            };
      +            devices = [ "magicant" "nbl-imba-2" ];
      +            id = "hgr3d-pfu3w";
      +          };
      +        };
      +      };
      +    };
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "storync.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:8384";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    34. +
    35. restic
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.restic {
      +
      +    # TODO
      +
      +  };
      +}
      +
      +
      +
      +
    36. +
    37. monitoring
      +
      +
      +
      { lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.monitoring {
      +
      +    sops.secrets = {
      +      grafanaadminpass = {
      +        owner = "grafana";
      +      };
      +      prometheusadminpass = {
      +        owner = "grafana";
      +      };
      +    };
      +
      +    users.users.nextcloud-exporter = {
      +      extraGroups = [ "nextcloud" ];
      +    };
      +
      +    users.users.grafana = {
      +      extraGroups = [ "users" ];
      +    };
      +
      +    services.grafana = {
      +      enable = true;
      +      dataDir = "/Vault/data/grafana";
      +      provision = {
      +        enable = true;
      +        datasources.settings = {
      +          datasources = [
      +            {
      +              name = "prometheus";
      +              type = "prometheus";
      +              url = "https://status.swarsel.win/prometheus";
      +              editable = false;
      +              access = "proxy";
      +              basicAuth = true;
      +              basicAuthUser = "admin";
      +              jsonData = {
      +                httpMethod = "POST";
      +                manageAlerts = true;
      +                prometheusType = "Prometheus";
      +                prometheusVersion = "> 2.50.x";
      +                cacheLevel = "High";
      +                disableRecordingRules = false;
      +                incrementalQueryOverlapWindow = "10m";
      +              };
      +              secureJsonData = {
      +                basicAuthPassword = "$__file{/run/secrets/prometheusadminpass}";
      +              };
      +            }
      +          ];
      +        };
      +      };
      +
      +      settings = {
      +        security.admin_password = "$__file{/run/secrets/grafanaadminpass}";
      +        server = {
      +          http_port = 3000;
      +          http_addr = "127.0.0.1";
      +          protocol = "http";
      +          domain = "status.swarsel.win";
      +        };
      +      };
      +    };
      +
      +    services.prometheus = {
      +      enable = true;
      +      webExternalUrl = "https://status.swarsel.win/prometheus";
      +      port = 9090;
      +      listenAddress = "127.0.0.1";
      +      globalConfig = {
      +        scrape_interval = "10s";
      +      };
      +      webConfigFile = ../../../programs/server/prometheus/web.config;
      +      scrapeConfigs = [
      +        {
      +          job_name = "node";
      +          static_configs = [{
      +            targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
      +          }];
      +        }
      +        {
      +          job_name = "zfs";
      +          static_configs = [{
      +            targets = [ "localhost:${toString config.services.prometheus.exporters.zfs.port}" ];
      +          }];
      +        }
      +        {
      +          job_name = "nginx";
      +          static_configs = [{
      +            targets = [ "localhost:${toString config.services.prometheus.exporters.nginx.port}" ];
      +          }];
      +        }
      +        {
      +          job_name = "nextcloud";
      +          static_configs = [{
      +            targets = [ "localhost:${toString config.services.prometheus.exporters.nextcloud.port}" ];
      +          }];
      +        }
      +      ];
      +      exporters = {
      +        node = {
      +          enable = true;
      +          port = 9000;
      +          enabledCollectors = [ "systemd" ];
      +          extraFlags = [ "--collector.ethtool" "--collector.softirqs" "--collector.tcpstat" "--collector.wifi" ];
      +        };
      +        zfs = {
      +          enable = true;
      +          port = 9134;
      +          pools = [
      +            "Vault"
      +          ];
      +        };
      +        restic = {
      +          enable = false;
      +          port = 9753;
      +        };
      +        nginx = {
      +          enable = true;
      +          port = 9113;
      +          sslVerify = false;
      +          scrapeUri = "http://localhost/nginx_status";
      +        };
      +        nextcloud = lib.mkIf config.swarselsystems.server.nextcloud {
      +          enable = true;
      +          port = 9205;
      +          url = "https://stash.swarsel.win/ocs/v2.php/apps/serverinfo/api/v1/info";
      +          username = "admin";
      +          passwordFile = config.sops.secrets.nextcloudadminpass.path;
      +        };
      +      };
      +    };
      +
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "status.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:3000";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +            "/prometheus" = {
      +              proxyPass = "http://localhost:9090";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    38. +
    39. Jenkins
      +
      +
      +
      { pkgs, lib, config, ... }:
      +{
      +  config = lib.mkIf config.swarselsystems.server.jenkins {
      +
      +    services.jenkins = {
      +      enable = true;
      +      withCLI = true;
      +      port = 8088;
      +      packages = [ pkgs.stdenv pkgs.git pkgs.jdk17 config.programs.ssh.package pkgs.nix ];
      +      listenAddress = "127.0.0.1";
      +      home = "/Vault/apps/jenkins";
      +    };
      +
      +
      +
      +    services.nginx = {
      +      virtualHosts = {
      +        "servant.swarsel.win" = {
      +          enableACME = true;
      +          forceSSL = true;
      +          acmeRoot = null;
      +          locations = {
      +            "/" = {
      +              proxyPass = "http://localhost:8088";
      +              extraConfig = ''
      +                client_max_body_size 0;
      +              '';
      +            };
      +          };
      +        };
      +      };
      +    };
      +  };
      +
      +}
      +
      +
      +
      +
    -

    3.3.2. Optional

    +

    3.3.3. Optional

    These sets of configuration do not need to be deployed on every host, for a multitude of reasons. @@ -7217,7 +7785,7 @@ This opens a few gaming ports and installs the steam configuration suite for gam environment.systemPackages = [ linuxKernel.packages.linux_6_10.xone - ]; + ]; } @@ -7250,6 +7818,23 @@ This sets the VirtualBox configuration. Guest should not be enabled if not direl

    +
  • VmWare
    +
    +

    +This sets the VirtualBox configuration. Guest should not be enabled if not direly needed, it will make rebuilds unbearably slow. +

    + +
    +
    _:
    +{
    +
    +  virtualisation.vmware.host.enable = true;
    +  virtualisation.vmware.guest.enable = true;
    +}
    +
    +
    +
    +
  • Auto-login

    @@ -7292,24 +7877,112 @@ This smashes Atmosphere 1.3.2 on the switch, which is what I am currenty using.

  • work

    -Integrates 1password mostly. There are more options at Work (home-manager side). +Options that I need specifically at work. There are more options at Work (home-manager side).

    -
    { pkgs, ... }:
    +
    { pkgs, config, ... }:
     {
    -  # boot.initrd.luks.yubikeySupport = true;
    -  programs._1password.enable = true;
    -  programs._1password-gui = {
    -    enable = true;
    -    polkitPolicyOwners = [ "swarsel" ];
    +  sops = {
    +    secrets = {
    +      clad = {
    +        owner = "swarsel";
    +        sopsFile = ../../../secrets/work/secrets.yaml;
    +      };
    +      dcad = {
    +        owner = "swarsel";
    +        sopsFile = ../../../secrets/work/secrets.yaml;
    +      };
    +      wsad = {
    +        owner = "swarsel";
    +        sopsFile = ../../../secrets/work/secrets.yaml;
    +      };
    +      imbad = {
    +        owner = "swarsel";
    +        sopsFile = ../../../secrets/work/secrets.yaml;
    +      };
    +    };
       };
    -  virtualisation.docker.enable = true;
    +
    +  # boot.initrd.luks.yubikeySupport = true;
    +  programs = {
    +    zsh.shellInit = ''
    +      export CLAD="$(cat ${config.sops.secrets.clad.path})"
    +      export DCAD="$(cat ${config.sops.secrets.dcad.path})"
    +      export GOVC_PASSWORD="$(cat ${config.sops.secrets.dcad.path})"
    +      export WSAD="$(cat ${config.sops.secrets.wsad.path})"
    +      export IMBAD="$(cat ${config.sops.secrets.imbad.path})"
    +      export DCUSER="dc_adm_schwarzaeugl@IMP.UNIVIE.AC.AT"
    +      export GOVC_USERNAME="dc_adm_schwarzaeugl@IMP.UNIVIE.AC.AT"
    +      export PACKER_SSH_EXTRA_ARGS='"--scp-extra-args","'-O'"'
    +    '';
    +
    +    browserpass.enable = true;
    +    _1password.enable = true;
    +    _1password-gui = {
    +      enable = true;
    +      polkitPolicyOwners = [ "swarsel" ];
    +    };
    +  };
    +
    +  virtualisation = {
    +    docker.enable = true;
    +    libvirtd = {
    +      enable = true;
    +      qemu = {
    +        package = pkgs.qemu_kvm;
    +        runAsRoot = true;
    +        swtpm.enable = true;
    +        ovmf = {
    +          enable = true;
    +          packages = [(pkgs.OVMF.override {
    +            secureBoot = true;
    +            tpmSupport = true;
    +          }).fd];
    +        };
    +      };
    +    };
    +  };
    +
       environment.systemPackages = with pkgs; [
    +    # (python39.withPackages (ps: with ps; [
    +    # cryptography
    +    # ]))
    +    #   docker
         python39
    -    docker
    +    qemu
    +    packer
    +    gnumake
    +    libisoburn
    +    govc
    +    terraform
       ];
     
    +
    +  services = {
    +    openssh = {
    +      enable = true;
    +      extraConfig = ''
    +        '';
    +    };
    +
    +    syncthing = {
    +      settings = {
    +        "winters" = {
    +          id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
    +        };
    +        folders = {
    +          "Documents" = {
    +            path = "/home/swarsel/Documents";
    +            devices = [ "magicant" "winters" ];
    +            id = "hgr3d-pfu3w";
    +          };
    +        };
    +      };
    +    };
    +  };
    +
    +  # cgroups v1 is required for centos7 dockers
       specialisation = {
         cgroup_v1.configuration = {
           boot.kernelParams = [
    @@ -7318,6 +7991,7 @@ Integrates 1password mostly. There are more options at 
     
     
    -
    _:
    +
    +_:
     {
       xdg.desktopEntries = {
     
    @@ -7929,6 +8551,51 @@ TODO: Non-NixOS machines (=sp3) should not use these by default, but instead the
         };
     
       };
    +
    +  xdg.mimeApps = {
    +
    +    enable = true;
    +    defaultApplications = {
    +      "x-scheme-handler/http" = [ "firefox.desktop" ];
    +      "x-scheme-handler/https" = [ "firefox.desktop" ];
    +      "x-scheme-handler/chrome" = [ "firefox.desktop" ];
    +      "text/plain" = [ "emacsclient.desktop" ];
    +      "text/csv" = [ "emacsclient.desktop" ];
    +      "text/html" = [ "firefox.desktop" ];
    +      "application/x-extension-htm" = [ "firefox.desktop" ];
    +      "application/x-extension-html" = [ "firefox.desktop" ];
    +      "application/x-extension-shtml" = [ "firefox.desktop" ];
    +      "application/xhtml+xml" = [ "firefox.desktop" ];
    +      "application/x-extension-xhtml" = [ "firefox.desktop" ];
    +      "application/x-extension-xht" = [ "firefox.desktop" ];
    +      "image/png" = [ "imv.desktop" ];
    +      "image/jpeg" = [ "imv.desktop" ];
    +      "image/gif" = [ "imv.desktop" ];
    +      "image/svg" = [ "imv.desktop" ];
    +      "image/webp" = [ "firefox.desktop" ];
    +      "image/vnd.adobe.photoshop" = [ "gimp.desktop" ];
    +      "image/vnd.dxf" = [ "org.inkscape.Inkscape.desktop" ];
    +      "audio/flac" = [ "mpv.desktop" ];
    +      "audio/mp3" = [ "mpv.desktop" ];
    +      "audio/ogg" = [ "mpv.desktop" ];
    +      "audio/wav" = [ "mpv.desktop" ];
    +      "video/mp4" = [ "umpv.desktop" ];
    +      "video/mkv" = [ "umpv.desktop" ];
    +      "video/flv" = [ "umpv.desktop" ];
    +      "video/3gp" = [ "umpv.desktop" ];
    +      "application/pdf" = [ "org.gnome.Evince.desktop" ];
    +      "application/metalink+xml" = [ "emacsclient.desktop" ];
    +      "application/sql" = [ "emacsclient.desktop" ];
    +      "application/vnd.ms-powerpoint" = [ "impress.desktop" ];
    +      "application/msword" = [ "writer.desktop" ];
    +      "application/vnd.ms-excel" = [ "calc.desktop" ];
    +    };
    +    associations = {
    +      added = {
    +        "application/x-zerosize" = [ "emacsclient.desktop" ];
    +      };
    +    };
    +  };
     }
     
    @@ -7976,12 +8643,13 @@ As for the `home.sessionVariables`, it should be noted that environment variable

    Also, we link some files to the users XDG configuration home: +Also in firefox `about:config > toolkit.legacyUserProfileCustomizations.stylesheets` to true.

      xdg.configFile = {
         "tridactyl/tridactylrc".source = ../../../programs/firefox/tridactyl/tridactylrc;
    -  "tridactyl/themes/base16-codeschool.css".source = ../../../programs/firefox/tridactyl/themes/base16-codeschool.css;
    +    "tridactyl/themes/base16-codeschool.css".source = ../../../programs/firefox/tridactyl/themes/base16-codeschool.css;
       };
     }
     
    @@ -8336,11 +9004,11 @@ The theme is handled by stylix. { programs.kitty = { enable = true; - keybindings = { - "ctrl+shift+left" = "no_op"; - "ctrl+shift+right" = "no_op"; - "ctrl+shift+home" = "no_op"; - "ctrl+shift+end" = "no_op"; + keybindings = { }; + settings = { + scrollback_lines = 10000; + enable_audio_bell = false; + notify_on_cmd_finish = "always 20"; }; }; } @@ -8359,28 +9027,32 @@ Here we set some aliases (some of them should be shellApplications instead) as w

    -
    { pkgs, ... }:
    +
    { config, pkgs, lib, ... }:
     {
       programs.zsh = {
         enable = true;
    -    shellAliases = {
    -      hg = "history | grep";
    -      hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;";
    -      nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;";
    -      nswitch-stay = "cd ~/.dotfiles; git restore flake.lock; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;";
    -      edithome = "e -w ~/.dotfiles/SwarselSystems.org";
    -      magit = "emacsclient -nc -e \"(magit-status)\"";
    -      config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME";
    -      g = "git";
    -      c = "git --git-dir=$HOME/.dotfiles/.git --work-tree=$HOME/.dotfiles/";
    -      passpush = "cd ~/.local/share/password-store; git add .; git commit -m 'pass file changes'; git push; cd -;";
    -      passpull = "cd ~/.local/share/password-store; git pull; cd -;";
    -      hotspot = "nmcli connection up local; nmcli device wifi hotspot;";
    -      cd = "z";
    -      cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\"";
    -      nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
    -      fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff";
    -    };
    +    shellAliases = lib.recursiveUpdate
    +      {
    +        hg = "history | grep";
    +        hmswitch = "cd ~/.dotfiles; home-manager --flake .#$(whoami)@$(hostname) switch; cd -;";
    +        nswitch = "cd ~/.dotfiles; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;";
    +        nswitch-stay = "cd ~/.dotfiles; git restore flake.lock; sudo nixos-rebuild --flake .#$(hostname) switch; cd -;";
    +        edithome = "e -w ~/.dotfiles/SwarselSystems.org";
    +        magit = "emacsclient -nc -e \"(magit-status)\"";
    +        config = "git --git-dir=$HOME/.cfg/ --work-tree=$HOME";
    +        g = "git";
    +        c = "git --git-dir=$HOME/.dotfiles/.git --work-tree=$HOME/.dotfiles/";
    +        passpush = "cd ~/.local/share/password-store; git add .; git commit -m 'pass file changes'; git push; cd -;";
    +        passpull = "cd ~/.local/share/password-store; git pull; cd -;";
    +        hotspot = "nmcli connection up local; nmcli device wifi hotspot;";
    +        cd = "z";
    +        cdr = "cd \"$( (find /home/swarsel/Documents/GitHub -maxdepth 1 && echo /home/swarsel/.dotfiles) | fzf )\"";
    +        nix-ldd = "LD_LIBRARY_PATH=$NIX_LD_LIBRARY_PATH ldd";
    +        fs-diff = "sudo mount -o subvol=/ /dev/mapper/cryptroot /mnt ; fs-diff";
    +        lt = "ls -lath";
    +        oldshell = "nix shell github:nixos/nixpkgs/\"$1\" \"$2\"";
    +      }
    +      config.swarselsystems.shellAliases;
         autosuggestion.enable = true;
         enableCompletion = true;
         syntaxHighlighting.enable = true;
    @@ -8410,9 +9082,384 @@ Here we set some aliases (some of them should be shellApplications instead) as w
         initExtra = ''
           bindkey "^[[1;5D" backward-word
           bindkey "^[[1;5C" forward-word
    +
    +      my-backward-delete-word() {
    +          # Copy the global WORDCHARS variable to a local variable. That way any
    +          # modifications are scoped to this function only
    +          local WORDCHARS=$WORDCHARS
    +          # Use bash string manipulation to remove `:` so our delete will stop at it
    +          WORDCHARS="''${WORDCHARS//:}"
    +          # Use bash string manipulation to remove `/` so our delete will stop at it
    +          WORDCHARS="''${WORDCHARS//\/}"
    +          # Use bash string manipulation to remove `.` so our delete will stop at it
    +          WORDCHARS="''${WORDCHARS//.}"
    +          # zle <widget-name> will run an existing widget.
    +          zle backward-delete-word
    +      }
    +      zle -N my-backward-delete-word
    +      bindkey '^H' my-backward-delete-word
    +
    +      # This will be our `ctrl+alt+w` command
    +      my-backward-delete-whole-word() {
    +          # Copy the global WORDCHARS variable to a local variable. That way any
    +          # modifications are scoped to this function only
    +          local WORDCHARS=$WORDCHARS
    +          # Use bash string manipulation to add `:` to WORDCHARS if it's not present
    +          # already.
    +          [[ ! $WORDCHARS == *":"* ]] && WORDCHARS="$WORDCHARS"":"
    +          # zle <widget-name> will run that widget.
    +          zle backward-delete-word
    +      }
    +      # `zle -N` will create a new widget that we can use on the command line
    +      zle -N my-backward-delete-whole-word
    +      # bind this new widget to `ctrl+alt+w`
    +      bindkey '^W' my-backward-delete-whole-word
    +
    +      vterm_printf() {
    +                      if [ -n "$TMUX" ] && ([ "''${TERM%%-*}" = "tmux" ] || [ "''${TERM%%-*}" = "screen" ]); then
    +                        # Tell tmux to pass the escape sequences through
    +                        printf "\ePtmux;\e\e]%s\007\e\\" "$1"
    +                      elif [ "''${TERM%%-*}" = "screen" ]; then
    +                        # GNU screen (screen, screen-256color, screen-256color-bce)
    +                        printf "\eP\e]%s\007\e\\" "$1"
    +                      else
    +                        printf "\e]%s\e\\" "$1"
    +                      fi
    +                               }
    +      vterm_prompt_end() {
    +            vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
    +      }
    +      setopt PROMPT_SUBST
    +      PROMPT=$PROMPT'%{$(vterm_prompt_end)%}'
    +
    +      vterm_cmd() {
    +          local vterm_elisp
    +          vterm_elisp=""
    +          while [ $# -gt 0 ]; do
    +              vterm_elisp="$vterm_elisp""$(printf '"%s" ' "$(printf "%s" "$1" | sed -e 's|\\|\\\\|g' -e 's|"|\\"|g')")"
    +              shift
    +          done
    +          vterm_printf "51;E$vterm_elisp"
    +      }
    +
         '';
       };
     }
    +
    +
    +
    +
  • +
  • zellij
    +
    +
    +
    _:
    +# { pkgs, config, ... }:
    +# let
    +# inherit (config.lib.stylix) colors;
    +#   sesh = pkgs.writeScriptBin "sesh" ''
    +#     #! /usr/bin/env sh
    +
    +#     # Taken from https://github.com/zellij-org/zellij/issues/884#issuecomment-1851136980
    +#     # select a directory using zoxide
    +#     ZOXIDE_RESULT=$(zoxide query --interactive)
    +#     # checks whether a directory has been selected
    +#     if [[ -z "$ZOXIDE_RESULT" ]]; then
    +#     	# if there was no directory, select returns without executing
    +#     	exit 0
    +#     fi
    +#     # extracts the directory name from the absolute path
    +#     SESSION_TITLE=$(echo "$ZOXIDE_RESULT" | sed 's#.*/##')
    +
    +#     # get the list of sessions
    +#     SESSION_LIST=$(zellij list-sessions -n | awk '{print $1}')
    +
    +#     # checks if SESSION_TITLE is in the session list
    +#     if echo "$SESSION_LIST" | grep -q "^$SESSION_TITLE$"; then
    +#     	# if so, attach to existing session
    +#     	zellij attach "$SESSION_TITLE"
    +#     else
    +#     	# if not, create a new session
    +#     	echo "Creating new session $SESSION_TITLE and CD $ZOXIDE_RESULT"
    +#     	cd $ZOXIDE_RESULT
    +#     	zellij attach -c "$SESSION_TITLE"
    +#     fi
    +#   '';
    +
    +# in
    +{
    +  programs.zellij = {
    +    enable = true;
    +  };
    +  home.packages = [
    +    # pkgs.tmate
    +    # sesh
    +  ];
    +  #   xdg.configFile."zellij/config.kdl".source = ../../../programs/zellij/config.kdl;
    +  #   xdg.configFile."zellij/layouts/default.kdl".text = ''
    +  #     layout {
    +  #         swap_tiled_layout name="vertical" {
    +  #             tab max_panes=5 {
    +  #                 pane split_direction="vertical" {
    +  #                     pane
    +  #                     pane { children; }
    +  #                 }
    +  #             }
    +  #             tab max_panes=8 {
    +  #                 pane split_direction="vertical" {
    +  #                     pane { children; }
    +  #                     pane { pane; pane; pane; pane; }
    +  #                 }
    +  #             }
    +  #             tab max_panes=12 {
    +  #                 pane split_direction="vertical" {
    +  #                     pane { children; }
    +  #                     pane { pane; pane; pane; pane; }
    +  #                     pane { pane; pane; pane; pane; }
    +  #                 }
    +  #             }
    +  #         }
    +
    +  #         swap_tiled_layout name="horizontal" {
    +  #             tab max_panes=5 {
    +  #                 pane
    +  #                 pane
    +  #             }
    +  #             tab max_panes=8 {
    +  #                 pane {
    +  #                     pane split_direction="vertical" { children; }
    +  #                     pane split_direction="vertical" { pane; pane; pane; pane; }
    +  #                 }
    +  #             }
    +  #             tab max_panes=12 {
    +  #                 pane {
    +  #                     pane split_direction="vertical" { children; }
    +  #                     pane split_direction="vertical" { pane; pane; pane; pane; }
    +  #                     pane split_direction="vertical" { pane; pane; pane; pane; }
    +  #                 }
    +  #             }
    +  #         }
    +
    +  #         swap_tiled_layout name="stacked" {
    +  #             tab min_panes=5 {
    +  #                 pane split_direction="vertical" {
    +  #                     pane
    +  #                     pane stacked=true { children; }
    +  #                 }
    +  #             }
    +  #         }
    +
    +  #         swap_floating_layout name="staggered" {
    +  #             floating_panes
    +  #         }
    +
    +  #         swap_floating_layout name="enlarged" {
    +  #             floating_panes max_panes=10 {
    +  #                 pane { x "5%"; y 1; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 2; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 3; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 4; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 5; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 6; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 7; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 8; width "90%"; height "90%"; }
    +  #                 pane { x "5%"; y 9; width "90%"; height "90%"; }
    +  #                 pane focus=true { x 10; y 10; width "90%"; height "90%"; }
    +  #             }
    +  #         }
    +
    +  #         swap_floating_layout name="spread" {
    +  #             floating_panes max_panes=1 {
    +  #                 pane {y "50%"; x "50%"; }
    +  #             }
    +  #             floating_panes max_panes=2 {
    +  #                 pane { x "1%"; y "25%"; width "45%"; }
    +  #                 pane { x "50%"; y "25%"; width "45%"; }
    +  #             }
    +  #             floating_panes max_panes=3 {
    +  #                 pane focus=true { y "55%"; width "45%"; height "45%"; }
    +  #                 pane { x "1%"; y "1%"; width "45%"; }
    +  #                 pane { x "50%"; y "1%"; width "45%"; }
    +  #             }
    +  #             floating_panes max_panes=4 {
    +  #                 pane { x "1%"; y "55%"; width "45%"; height "45%"; }
    +  #                 pane focus=true { x "50%"; y "55%"; width "45%"; height "45%"; }
    +  #                 pane { x "1%"; y "1%"; width "45%"; height "45%"; }
    +  #                 pane { x "50%"; y "1%"; width "45%"; height "45%"; }
    +  #             }
    +  #         }
    +
    +  #         default_tab_template {
    +  #             pane size=2 borderless=true {
    +  #                 plugin location="file://${pkgs.zjstatus}/bin/zjstatus.wasm" {
    +  #                     format_left   "{mode}#[bg=#${colors.base00}] {tabs}"
    +  #                     format_center ""
    +  #                     format_right  "#[bg=#${colors.base00},fg=#${colors.base0D}]#[bg=#${colors.base0D},fg=#${colors.base01},bold] #[bg=#${colors.base02},fg=#${colors.base05},bold] {session} #[bg=#${colors.base03},fg=#${colors.base05},bold]"
    +  #                     format_space  ""
    +  #                     format_hide_on_overlength "true"
    +  #                     format_precedence "crl"
    +
    +  #                     border_enabled  "false"
    +  #                     border_char     "─"
    +  #                     border_format   "#[fg=#6C7086]{char}"
    +  #                     border_position "top"
    +
    +  #                     mode_normal        "#[bg=#${colors.base0B},fg=#${colors.base02},bold] NORMAL#[bg=#${colors.base03},fg=#${colors.base0B}]█"
    +  #                     mode_locked        "#[bg=#${colors.base04},fg=#${colors.base02},bold] LOCKED #[bg=#${colors.base03},fg=#${colors.base04}]█"
    +  #                     mode_resize        "#[bg=#${colors.base08},fg=#${colors.base02},bold] RESIZE#[bg=#${colors.base03},fg=#${colors.base08}]█"
    +  #                     mode_pane          "#[bg=#${colors.base0D},fg=#${colors.base02},bold] PANE#[bg=#${colors.base03},fg=#${colors.base0D}]█"
    +  #                     mode_tab           "#[bg=#${colors.base07},fg=#${colors.base02},bold] TAB#[bg=#${colors.base03},fg=#${colors.base07}]█"
    +  #                     mode_scroll        "#[bg=#${colors.base0A},fg=#${colors.base02},bold] SCROLL#[bg=#${colors.base03},fg=#${colors.base0A}]█"
    +  #                     mode_enter_search  "#[bg=#${colors.base0D},fg=#${colors.base02},bold] ENT-SEARCH#[bg=#${colors.base03},fg=#${colors.base0D}]█"
    +  #                     mode_search        "#[bg=#${colors.base0D},fg=#${colors.base02},bold] SEARCHARCH#[bg=#${colors.base03},fg=#${colors.base0D}]█"
    +  #                     mode_rename_tab    "#[bg=#${colors.base07},fg=#${colors.base02},bold] RENAME-TAB#[bg=#${colors.base03},fg=#${colors.base07}]█"
    +  #                     mode_rename_pane   "#[bg=#${colors.base0D},fg=#${colors.base02},bold] RENAME-PANE#[bg=#${colors.base03},fg=#${colors.base0D}]█"
    +  #                     mode_session       "#[bg=#${colors.base0E},fg=#${colors.base02},bold] SESSION#[bg=#${colors.base03},fg=#${colors.base0E}]█"
    +  #                     mode_move          "#[bg=#${colors.base0F},fg=#${colors.base02},bold] MOVE#[bg=#${colors.base03},fg=#${colors.base0F}]█"
    +  #                     mode_prompt        "#[bg=#${colors.base0D},fg=#${colors.base02},bold] PROMPT#[bg=#${colors.base03},fg=#${colors.base0D}]█"
    +  #                     mode_tmux          "#[bg=#${colors.base09},fg=#${colors.base02},bold] TMUX#[bg=#${colors.base03},fg=#${colors.base09}]█"
    +
    +  #                     // formatting for inactive tabs
    +  #                     tab_normal              "#[bg=#${colors.base03},fg=#${colors.base0D}]█#[bg=#${colors.base0D},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{floating_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +  #                     tab_normal_fullscreen   "#[bg=#${colors.base03},fg=#${colors.base0D}]█#[bg=#${colors.base0D},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{fullscreen_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +  #                     tab_normal_sync         "#[bg=#${colors.base03},fg=#${colors.base0D}]█#[bg=#${colors.base0D},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{sync_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +
    +  #                     // formatting for the current active tab
    +  #                     tab_active              "#[bg=#${colors.base03},fg=#${colors.base09}]█#[bg=#${colors.base09},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{floating_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +  #                     tab_active_fullscreen   "#[bg=#${colors.base03},fg=#${colors.base09}]█#[bg=#${colors.base09},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{fullscreen_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +  #                     tab_active_sync         "#[bg=#${colors.base03},fg=#${colors.base09}]█#[bg=#${colors.base09},fg=#${colors.base02},bold]{index} #[bg=#${colors.base02},fg=#${colors.base05},bold] {name}{sync_indicator}#[bg=#${colors.base03},fg=#${colors.base02},bold]█"
    +
    +  #                     // separator between the tabs
    +  #                     tab_separator           "#[bg=#${colors.base00}] "
    +
    +  #                     // indicators
    +  #                     tab_sync_indicator       " "
    +  #                     tab_fullscreen_indicator " 󰊓"
    +  #                     tab_floating_indicator   " 󰹙"
    +
    +  #                     command_git_branch_command     "git rev-parse --abbrev-ref HEAD"
    +  #                     command_git_branch_format      "#[fg=blue] {stdout} "
    +  #                     command_git_branch_interval    "10"
    +  #                     command_git_branch_rendermode  "static"
    +
    +  #                     datetime        "#[fg=#6C7086,bold] {format} "
    +  #                     datetime_format "%A, %d %b %Y %H:%M"
    +  #                     datetime_timezone "Europe/London"
    +  #                 }
    +  #             }
    +  #             children
    +  #         }
    +  #     }
    +  #   '';
    +
    +
    +}
    +
    +
    +
    +
  • +
  • tmux
    +
    +
    +
    +  { pkgs, ... }:
    +let
    +  tmux-super-fingers = pkgs.tmuxPlugins.mkTmuxPlugin
    +    {
    +      pluginName = "tmux-super-fingers";
    +      version = "unstable-2023-01-06";
    +      src = pkgs.fetchFromGitHub {
    +        owner = "artemave";
    +        repo = "tmux_super_fingers";
    +        rev = "2c12044984124e74e21a5a87d00f844083e4bdf7";
    +        sha256 = "sha256-cPZCV8xk9QpU49/7H8iGhQYK6JwWjviL29eWabuqruc=";
    +      };
    +    };
    +in
    +{
    +
    +  home.packages = with pkgs; [
    +    lsof
    +    sesh
    +  ];
    +
    +  programs.tmux = {
    +    enable = true;
    +    shell = "${pkgs.zsh}/bin/zsh";
    +    terminal = "tmux-256color";
    +    historyLimit = 100000;
    +    plugins = with pkgs;
    +      [
    +        tmuxPlugins.tmux-thumbs
    +        {
    +          plugin = tmux-super-fingers;
    +          extraConfig = "set -g @super-fingers-key f";
    +        }
    +
    +        tmuxPlugins.sensible
    +        # must be before continuum edits right status bar
    +        {
    +          plugin = tmuxPlugins.catppuccin;
    +          extraConfig = ''
    +            set -g @catppuccin_flavour 'frappe'
    +            set -g @catppuccin_window_tabs_enabled on
    +            set -g @catppuccin_date_time "%H:%M"
    +          '';
    +        }
    +        {
    +          plugin = tmuxPlugins.resurrect;
    +          extraConfig = ''
    +            set -g @resurrect-strategy-vim 'session'
    +            set -g @resurrect-strategy-nvim 'session'
    +            set -g @resurrect-capture-pane-contents 'on'
    +          '';
    +        }
    +        {
    +          plugin = tmuxPlugins.continuum;
    +          extraConfig = ''
    +            set -g @continuum-restore 'on'
    +            set -g @continuum-boot 'on'
    +            set -g @continuum-save-interval '10'
    +          '';
    +        }
    +        tmuxPlugins.better-mouse-mode
    +        tmuxPlugins.yank
    +      ];
    +    extraConfig = ''
    +      set -g default-terminal "tmux-256color"
    +      set -ag terminal-overrides ",xterm-256color:RGB"
    +
    +      set-option -g prefix C-a
    +      unbind-key C-b
    +      bind-key C-a send-prefix
    +
    +      set -g mouse on
    +
    +      # Open new split at cwd of current split
    +      bind | split-window -h -c "#{pane_current_path}"
    +      bind - split-window -v -c "#{pane_current_path}"
    +
    +      # Use vim keybindings in copy mode
    +      set-window-option -g mode-keys vi
    +
    +      # v in copy mode starts making selection
    +      bind-key -T copy-mode-vi v send-keys -X begin-selection
    +      bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle
    +      bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
    +
    +      # Escape turns on copy mode
    +      bind Escape copy-mode
    +
    +      set-option -g status-position top
    +
    +      # make Prefix p paste the buffer.
    +      unbind p
    +      bind p paste-buffer
    +
    +    '';
    +  };
    +}
    +
    +
     
    @@ -8645,7 +9692,7 @@ The rest of the related configuration is found here:
    -
    { config, lib, pkgs, ... }:
    +
    { config, lib, ... }:
     {
       programs.waybar = {
     
    @@ -8692,18 +9739,18 @@ The rest of the related configuration is found here:
               on-click = "xdg-open https://github.com/notifications";
             };
     
    -        "custom/nix-updates" = {
    -          exec = "update-checker";
    -          on-click = "update-checker && notify-send 'The system has been updated'";
    -          interval = "once";
    -          tooltip = true;
    -          return-type = "json";
    -          format = "{} {icon}";
    -          format-icon = {
    -            "has-updates" = "";
    -            "updated" = " ";
    -          };
    -        };
    +        # "custom/nix-updates" = {
    +        #   exec = "update-checker";
    +        #   on-click = "update-checker && notify-send 'The system has been updated'";
    +        #   interval = "once";
    +        #   tooltip = true;
    +        #   return-type = "json";
    +        #   format = "{} {icon}";
    +        #   format-icon = {
    +        #     "has-updates" = "";
    +        #     "updated" = " ";
    +        #   };
    +        # };
     
             idle_inhibitor = {
               format = "{icon}";
    @@ -8938,11 +9985,12 @@ I used to build the firefox addon bypass-paywalls-clean myself here
         enable = true;
         package = pkgs.firefox; # uses overrides
         policies = {
    -      CaptivePortal = false;
    +      # CaptivePortal = false;
           DisableFirefoxStudies = true;
           DisablePocket = true;
           DisableTelemetry = true;
           DisableFirefoxAccounts = false;
    +      DisplayBookmarksToolbar = "always";
           NoDefaultBookmarks = true;
           OfferToSaveLogins = false;
           OfferToSaveLoginsDefault = false;
    @@ -9065,6 +10113,7 @@ This enables phone/computer communication, including sending clipboard, files et
         enable = true;
         indicator = true;
       };
    +
     }
     
    @@ -9165,7 +10214,7 @@ Currently, I am too lazy to explain every option here, but most of it is very se

    -
    { config, pkgs, lib, ... }:
    +
    { config, lib, ... }:
     let
       inherit (config.swarselsystems) monitors;
       eachMonitor = _name: monitor: {
    @@ -9220,6 +10269,7 @@ in
                 "${modifier}+o" = "exec pass-fuzzel --otp";
                 "${modifier}+Shift+p" = "exec pass-fuzzel --type";
                 "${modifier}+Shift+o" = "exec pass-fuzzel --otp --type";
    +            "${modifier}+Ctrl+p" = "exec 1password --quick-acces";
                 "${modifier}+Escape" = "mode $exit";
                 "${modifier}+Shift+Escape" = "exec kitty -o confirm_os_window_close=0 btm";
                 "${modifier}+s" = "exec grim -g \"$(slurp)\" -t png - | wl-copy -t image/png";
    @@ -9247,6 +10297,14 @@ in
                 "${modifier}+Ctrl+Shift+m" = "move container to workspace 11:M";
                 "${modifier}+Ctrl+s" = "workspace 12:S";
                 "${modifier}+Ctrl+Shift+s" = "move container to workspace 12:S";
    +            "${modifier}+Ctrl+e" = "workspace 13:E";
    +            "${modifier}+Ctrl+Shift+e" = "move container to workspace 13:E";
    +            "${modifier}+Ctrl+t" = "workspace 14:T";
    +            "${modifier}+Ctrl+Shift+t" = "move container to workspace 14:T";
    +            "${modifier}+Ctrl+l" = "workspace 15:L";
    +            "${modifier}+Ctrl+Shift+l" = "move container to workspace 15:L";
    +            "${modifier}+Ctrl+f" = "workspace 16:F";
    +            "${modifier}+Ctrl+Shift+f" = "move container to workspace 16:F";
                 "${modifier}+Left" = "focus left";
                 "${modifier}+Right" = "focus right";
                 "${modifier}+Down" = "focus down";
    @@ -9302,8 +10360,8 @@ in
             titlebar = false;
           };
           assigns = {
    -        "1:一" = [{ app_id = "firefox"; }];
    -        "10:十" = [{ app_id = "teams-for-linux"; }];
    +        "16:F" = [{ app_id = "firefox"; }];
    +        "15:L" = [{ app_id = "teams-for-linux"; }];
           };
           floating = {
             border = 1;
    @@ -9318,6 +10376,7 @@ in
               { title = "Syncthing Tray"; }
               { app_id = "SchildiChat"; }
               { app_id = "Element"; }
    +          { class = "1Password"; }
               { app_id = "com.nextcloud.desktopclient.nextcloud"; }
               { app_id = "gnome-system-monitor"; }
               { title = "(?:Open|Save) (?:File|Folder|As)"; }
    @@ -9353,6 +10412,12 @@ in
                   app_id = "firefox";
                 };
               }
    +          {
    +            command = "opacity 0.99";
    +            criteria = {
    +              app_id = "chromium-browser";
    +            };
    +          }
               {
                 command = "sticky enable, shadows enable";
                 criteria = {
    @@ -9524,10 +10589,9 @@ The rest of the settings is at 
     
    { pkgs, ... }:
    -
     {
       home.packages = with pkgs; [
    -    lutris
    +    stable.lutris
         wine
         libudev-zero
         dwarfs
    @@ -9540,6 +10604,7 @@ The rest of the settings is at (fset 'epg-wait-for-status
     (add-hook 'emacs-startup-hook
               (lambda ()
                 (progn
    -              (setq gc-cons-threshold (* 1000 1000 8)
    +              ;; (setq gc-cons-threshold (* 1000 1000 8)
    +              ;; (setq gc-cons-threshold #x40000000
    +                 (setq gc-cons-threshold (* 32 1024 1024)
                         gc-cons-percentage 0.1
    +                    jit-lock-defer-time 0.05
    +                    read-process-output-max (* 1024 1024)
                         file-name-handler-alist swarsel-file-name-handler-alist
                         vc-handled-backends swarsel-vc-handled-backends)
                   (fset 'epg-wait-for-status 'ignore)
    @@ -10699,14 +11795,14 @@ Used here: General org-mode
     
     (defun swarsel/org-mode-setup ()
    -  (org-indent-mode)
    +  ;; (org-indent-mode)
       (variable-pitch-mode 1)
       ;;(auto-fill-mode 0)
    -  (setq display-line-numbers-type 'relative
    -        display-line-numbers-current-absolute 1
    -        display-line-numbers-width-start nil
    -        display-line-numbers-width 6
    -        display-line-numbers-grow-only 1)
    +  ;; (setq display-line-numbers-type 'relative
    +  ;;       display-line-numbers-current-absolute 1
    +  ;;       display-line-numbers-width-start nil
    +  ;;       display-line-numbers-width 6
    +  ;;       display-line-numbers-grow-only 1)
       (add-hook 'org-tab-first-hook 'org-end-of-line)
       (visual-line-mode 1))
     
    @@ -10758,17 +11854,19 @@ We set a hook that runs everytime we save the file. It would be a bit more effic
         (shell-command "nixpkgs-fmt . > /dev/null")))
     
       (defun swarsel/org-babel-tangle-config ()
    +  (interactive)
         (when (string-equal (buffer-file-name)
                             swarsel-swarsel-org-filepath)
           ;; Dynamic scoping to the rescue
           (let ((org-confirm-babel-evaluate nil))
             ;; (org-html-export-to-html)
             (org-babel-tangle)
    -        (swarsel/run-formatting))))
    +        ;; (swarsel/run-formatting)
    +        )))
     
       (setq org-html-htmlize-output-type nil)
     
    -  (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'swarsel/org-babel-tangle-config)))
    +  ;; (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'swarsel/org-babel-tangle-config)))
     
     
    @@ -10942,6 +12040,24 @@ This formats the org code block at point in accordance to the + + +
  • +
  • Disable garbace collection while minibuffer is active
    +
    +
    +
    +(defun swarsel/minibuffer-setup-hook ()
    +  (setq gc-cons-threshold most-positive-fixnum))
    +
    +(defun swarsel/minibuffer-exit-hook ()
    +  (setq gc-cons-threshold (* 32 1024 1024)))
    +
    +(add-hook 'minibuffer-setup-hook #'swarsel/minibuffer-setup-hook)
    +(add-hook 'minibuffer-exit-hook #'swarsel/minibuffer-exit-hook)
    +
    +
     
    @@ -11067,8 +12183,14 @@ I also define some keybinds to some combinations directly. Those are used mostly "<DUMMY-m>" 'swarsel/last-buffer "M-\\" 'indent-region "C-<f9>" 'my-python-shell-run + "<Paste>" 'yank + "<Cut>" 'kill-region + "<Copy>" 'kill-ring-save + "<undo>" 'evil-undo + "<redo>" 'evil-redo ) + @@ -11204,7 +12326,7 @@ Here I set up some things that are too minor to put under other categories.
     ;; use UTF-8 everywhere
     (set-language-environment "UTF-8")
    -
    +(profiler-start 'cpu)
     ;; set default font size
     (defvar swarsel/default-font-size 130)
     (setq swarsel-standard-font "FiraCode Nerd Font Mono"
    @@ -11223,7 +12345,16 @@ Here I set up some things that are too minor to put under other categories.
     (setq require-final-newline t)
     (winner-mode 1)
     (setq load-prefer-newer t)
    -
    +(setq-default bidi-paragraph-direction 'left-to-right
    +              bidi-display-reordering 'left-to-right
    +              bidi-inhibit-bpa t)
    +(global-so-long-mode)
    +(setq process-adaptive-read-buffering nil) ;; not sure if this is a good idea
    +(setq fast-but-imprecise-scrolling t
    +      redisplay-skip-fontification-on-input t
    +      inhibit-compacting-font-caches t)
    +(setq idle-update-delay 1.0
    +      which-func-update-delay 1.0)
     (setq undo-limit 80000000
           evil-want-fine-undo t
           auto-save-default t
    @@ -11241,8 +12372,8 @@ Here I set up some things that are too minor to put under other categories.
           initial-scratch-message nil)
     
     (add-hook 'prog-mode-hook 'display-line-numbers-mode)
    -(add-hook 'text-mode-hook 'display-line-numbers-mode)
    -(global-visual-line-mode 1)
    +;; (add-hook 'text-mode-hook 'display-line-numbers-mode)
    +;; (global-visual-line-mode 1)
     
     
    @@ -11278,12 +12409,35 @@ When Emacs compiles stuff, it often shows a bunch of warnings that I do not need (setq native-comp-async-report-warnings-errors 'silent) ; Emacs 28 with native compilation (setq native-compile-prune-cache t)) ; Emacs 29 + + + + +
    +

    4.3.4. Better garbage collection

    +
    +
    +
    (setq garbage-collection-messages t)
    +(defmacro k-time (&rest body)
    +  "Measure and return the time it takes evaluating BODY."
    +  `(let ((time (current-time)))
    +     ,@body
    +     (float-time (time-since time))))
    +
    +
    +;; When idle for 15sec run the GC no matter what.
    +(defvar k-gc-timer
    +  (run-with-idle-timer 15 t
    +                       (lambda ()
    +                         (message "Garbage Collector has run for %.06fsec"
    +                                  (k-time (garbage-collect))))))
    +
     
    -

    4.3.4. Indentation

    +

    4.3.5. Indentation

    Here I define several options related to indentation; I first make it so that only whitespace will be used instead of tab characters for indentation, and I also set a small standard indent. @@ -11326,7 +12480,7 @@ Lastly, I load the highlight-indent-guides package. This adds a nea

    -

    4.3.5. Scrolling

    +

    4.3.6. Scrolling

    By default, emacs scrolls half a page when reaching the bottom of the buffer. This is extremely annoying. This sets up more granular scrolling that allows scrolling with a mouse wheel or the two-finger touchscreen gesture. This now also works in buffers with a very small frame. @@ -11356,7 +12510,7 @@ By default, emacs scrolls half a page when reaching the bottom of the buffer. Th

    -

    4.3.6. Evil

    +

    4.3.7. Evil

      @@ -11381,11 +12535,18 @@ Also, I setup initial modes for several major-modes depending on what I deem fit (setq evil-want-C-i-jump nil) ; jumping with C-i (setq evil-want-Y-yank-to-eol t) ; give Y some utility (setq evil-shift-width 2) ; uniform indent - (setq evil-respect-visual-line-mode t) ; i am torn on this one + (setq evil-respect-visual-line-mode nil) ; i am torn on this one (setq evil-split-window-below t) (setq evil-vsplit-window-right t) :config (evil-mode 1) + + ;; make normal mode respect wrapped lines + (define-key evil-normal-state-map (kbd "j") 'evil-next-visual-line) + (define-key evil-normal-state-map (kbd "<down>") 'evil-next-visual-line) + (define-key evil-normal-state-map (kbd "k") 'evil-previous-visual-line) + (define-key evil-normal-state-map (kbd "<up>") 'evil-previous-visual-line) + (define-key evil-normal-state-map (kbd "C-z") nil) (define-key evil-insert-state-map (kbd "C-z") nil) (define-key evil-visual-state-map (kbd "C-z") nil) @@ -11480,7 +12641,7 @@ This minor-mode adds functionality for doing better surround-commands; for examp
    -

    4.3.7. ispell

    +

    4.3.8. ispell

    This should setup a wordlist that can be used as a dictionary. However, for some reason this does not work, and I will need to further investigate this issue. @@ -11496,7 +12657,7 @@ This should setup a wordlist that can be used as a dictionary. However, for some

    -

    4.3.8. Font Configuration

    +

    4.3.9. Font Configuration

    Here I define my fonts to be used. Honestly I do not understand the face-attributes and pitches of emacs all too well. It seems this configuration works fine, but I might have to revisit this at some point in the future. @@ -11524,7 +12685,7 @@ Here I define my fonts to be used. Honestly I do not understand the face-attribu

    -

    4.3.9. Theme

    +

    4.3.10. Theme

    I have grown to love the doom-citylights theme and have modeled my whole system after it. Also solaire-mode is a nice mode that inverts the alt-faces with the normal faces for specific 'minor' buffers (like Help-buffers). @@ -11550,7 +12711,7 @@ I have grown to love the doom-citylights theme and have modeled my

    -

    4.3.10. Icons

    +

    4.3.11. Icons

    This section loads the base icons used in my configuration. I am using nerd-icons over all-the-icons since the former seems to have more integrations with different packages than the latter. @@ -11573,7 +12734,7 @@ Used in:

    -

    4.3.11. Variable Pitch Mode

    +

    4.3.12. Variable Pitch Mode

    This minor mode allows mixing fixed and variable pitch fonts within the same buffer. @@ -11594,7 +12755,7 @@ This minor mode allows mixing fixed and variable pitch fonts within the same buf

    -

    4.3.12. Modeline

    +

    4.3.13. Modeline

    Here I set up the modeline with some information that I find useful. Specficially I am using the doom modeline. Most informations I disable for it, except for the cursor information (row + column) as well as a widget for mu4e and git information. @@ -11617,7 +12778,7 @@ Here I set up the modeline with some information that I find useful. Specficiall

    -

    4.3.13. Helper Modes

    +

    4.3.14. Helper Modes

      @@ -11853,7 +13014,7 @@ This pair of packages provides information on keybinds in addition to function n
    -

    4.3.14. Ligatures

    +

    4.3.15. Ligatures

    Personally, I think ligatures are fancy. With this mode, they stay 'cursorable'. However, I do not need them in all modes, so I only use them in programming modes. @@ -11885,7 +13046,7 @@ Personally, I think ligatures are fancy. With this mode, they stay 'cursorable'.

    -

    4.3.15. Popup (popper) + Shackle Buffers

    +

    4.3.16. Popup (popper) + Shackle Buffers

    The popper package allows to declare different buffers as 'popup-type', which sort of acts like a scratchpad. It can be toggled at any time using popper-toggle and the resulting frame can be freely customized (with shackle) to a certain size. It is also possible to prevent a buffer from appearing - I do this for example to the *Warnings* buffer, since usually I am not interested in it's output. @@ -11938,7 +13099,7 @@ The popper package allows to declare different buffers as 'popup-type', which so

    -

    4.3.16. Indicate first and last line of buffer

    +

    4.3.17. Indicate first and last line of buffer

    This places little angled indicators on the fringe of a window which indicate buffer boundaries. This is not super useful, but makes use of a space that I want to keep for aesthetic reasons anyways and makes it a bit more useful in the process. @@ -11953,7 +13114,7 @@ This places little angled indicators on the fringe of a window which indicate bu

    @@ -12231,18 +13394,20 @@ It also offers a very useful utility of exporting org-mode buffers to different
    -
    -(org-babel-do-load-languages
    - 'org-babel-load-languages
    - '((emacs-lisp . t)
    -   (python . t)
    -   (js . t)
    -   (shell . t)
    -   ))
    +
    (setq org-src-preserve-indentation nil)
     
    -(push '("conf-unix" . conf-unix) org-src-lang-modes)
    +  (org-babel-do-load-languages
    +   'org-babel-load-languages
    +   '((emacs-lisp . t)
    +     (python . t)
    +     (js . t)
    +     (shell . t)
    +     ))
     
    -(setq org-export-with-broken-links 'mark)
    +  (push '("conf-unix" . conf-unix) org-src-lang-modes)
    +
    +  (setq org-export-with-broken-links 'mark)
    +  (setq org-confirm-babel-evaluate nil)
     
     
    @@ -12407,10 +13572,10 @@ Recently I have grown fond of holding presentations using Emacs :) (setq visual-fill-column-width 90) (setq indicate-buffer-boundaries nil) (setq inhibit-message nil) - (breadcrumb-mode 0) + ;; (breadcrumb-mode 0) (org-display-inline-images) (global-hl-line-mode 0) - (display-line-numbers-mode 0) + ;; (display-line-numbers-mode 0) (org-modern-mode 0) (evil-insert-state 1) (beginning-of-buffer) @@ -12434,9 +13599,9 @@ Recently I have grown fond of holding presentations using Emacs :) (setq visual-fill-column-width 150) (setq indicate-buffer-boundaries t) (setq inhibit-message nil) - (breadcrumb-mode 1) + ;; (breadcrumb-mode 1) (global-hl-line-mode 1) - (display-line-numbers-mode 1) + ;; (display-line-numbers-mode 1) (org-remove-inline-images) (org-modern-mode 1) (evil-normal-state 1) @@ -12490,12 +13655,85 @@ This adds a rudimentary nix-mode to Emacs. I have not really tried this out, as (use-package nix-mode :mode "\\.nix\\'") + + + + +
    +

    4.4.3. HCL Mode

    +
    +

    +This adds support for Hashicorp Configuration Language. I need this at work. +

    + +
    +
    +(use-package hcl-mode
    +  :mode "\\.hcl\\'"
    +  :config
    +  (setq hcl-indent-level 2))
    +
    +
    +
    +
    +
    +
    +

    4.4.4. Jenkinsfile/Groovy

    +
    +

    +This adds support for Groovy, which I specifically need to work with Jenkinsfiles. I need this at work. +

    + +
    +
    +(use-package groovy-mode)
    +
    +(use-package jenkinsfile-mode
    +  :mode "Jenkinsfile")
    +
    +
    +
    +
    +
    +
    +

    4.4.5. Dockerfile

    +
    +

    +This adds support for Dockerfiles. I need this at work. +

    + +
    +
    +(use-package dockerfile-mode
    +  :mode "Dockerfile")
    +
    +
    +
    +
    +
    +
    +

    4.4.6. Terraform Mode

    +
    +

    +This adds support for Terraform configuration files. I need this at work. +

    + +
    +
    +(use-package terraform-mode
    +  :mode "\\.tf\\'"
    +  :config
    +  (setq terraform-indent-level 2)
    +  (setq terraform-format-on-save t))
    +
    +(add-hook 'terraform-mode-hook #'outline-minor-mode)
    +
     
    -

    4.4.3. nixpkgs-fmt

    +

    4.4.7. nixpkgs-fmt

    Adds functions for formatting nix code. @@ -12510,7 +13748,7 @@ Adds functions for formatting nix code.

    -

    4.4.4. Markdown Mode

    +

    4.4.8. Markdown Mode

      @@ -12548,7 +13786,7 @@ Adds functions for formatting nix code.
    -

    4.4.5. Olivetti

    +

    4.4.9. Olivetti

    Olivetti is a mode specialized for writing prose in Emacs. I went for a very simple setup with little distractions. @@ -12570,7 +13808,7 @@ This mode is not automatically activated anywhere because I only rarely need it.

    -

    4.4.6. darkroom

    +

    4.4.10. darkroom

    Darkroom is package that reduces all forms of distraction to a minimum - this can be useful when simply reading a file for example. For this mode I have increased the text scale by a large margin to make for comfortable reading @@ -12588,7 +13826,7 @@ This mode is not automatically activated anywhere because I only rarely need it.

    -

    4.4.7. Ripgrep

    +

    4.4.11. Ripgrep

    This is the ripgrep command for Emacs. @@ -12603,7 +13841,7 @@ This is the ripgrep command for Emacs.

    -

    4.4.8. Tree-sitter

    +

    4.4.12. Tree-sitter

    Tree-sitter is a parsing library integrated into Emacs to provide better syntax highlighting and code analysis. It generates concrete syntax trees for source code, enabling more accurate and efficient text processing. Emacs' tree-sitter integration enhances language support, offering features like incremental parsing and precise syntax-aware editing. This improves the development experience by providing robust and dynamic syntax features, making it easier for me to navigate and manipulate code. @@ -12661,7 +13899,7 @@ In order to update the language grammars, run the next command below.

    -

    4.4.9. direnv (envrc)

    +

    4.4.13. direnv (envrc)

    @@ -12674,7 +13912,7 @@ In order to update the language grammars, run the next command below.
     
    -

    4.4.10. avy

    +

    4.4.14. avy

    avy provides the ability to search for any character on the screen (not only in the current buffer!) - I enjoy this utility a lot and use it possibly even more often than the native vim commands. @@ -12693,7 +13931,7 @@ In order to update the language grammars, run the next command below.

    -

    4.4.11. crdt (Collaborative Editing)

    +

    4.4.15. crdt (Collaborative Editing)

    With this it is possible to work on the same file collaboratively. I have never tried it out, but it sounds cool. @@ -12708,7 +13946,7 @@ With this it is possible to work on the same file collaboratively. I have never

    -

    4.4.12. devdocs

    +

    4.4.16. devdocs

    devdocs is a very nice package that provides documentation from https:devdocs.io. This is very useful since e.g. pyright provides only a very bad documentation and I do not want to leave Emacs all the time just to read documentation. @@ -12744,7 +13982,7 @@ To install a documentation, use the devdocs=install command and sel

    -

    4.4.13. Projectile

    +

    4.4.17. Projectile

    projectile is useful for keeping track of your git projects within Emacs. I mostly use it to quickly switch between projects. @@ -12769,7 +14007,7 @@ projectile is useful for keeping track of your git projects within Emacs. I most

    -

    4.4.14. Magit

    +

    4.4.18. Magit

    magit is the best git utility I have ever used - it has a beautiful interface and is very verbose. Here I mostly just setup the list of repositories that I want to expost to magit. @@ -12794,7 +14032,7 @@ Also, Emacs needs a little extra love to accept my Yubikey for git commits etc.

    -

    4.4.15. Yubikey support

    +

    4.4.19. Yubikey support

    The following settings are needed to make sure emacs works for magit commits and pushes. It is not a beautiful solution since commiting uses pinentry-emacs and pushing uses pinentry-gtk2, but it works for now at least. @@ -12814,7 +14052,7 @@ The following settings are needed to make sure emacs works for magit commits and

    -

    4.4.16. Forge

    +

    4.4.20. Forge

    NOTE: Make sure to configure a GitHub token before using this package! @@ -12852,7 +14090,7 @@ machine api.github.com login USERNAMEforge password 012345abcdef

    -

    4.4.17. git-timemachine

    +

    4.4.21. git-timemachine

    This is just a nice utility to browse different versions of a file of a git project within Emacs. @@ -12869,7 +14107,7 @@ This is just a nice utility to browse different versions of a file of a git proj

    -

    4.4.18. Delimiters (brackets): rainbow-delimiters, highlight-parentheses

    +

    4.4.22. Delimiters (brackets): rainbow-delimiters, highlight-parentheses

    • rainbow-delimiters colors all delimiters, also ones not in current selection
    • @@ -12892,18 +14130,18 @@ I am not completely sure on electric-pair-mode yet, sometimes it is very helpful (setq highlight-parentheses-background-colors '("magenta" "blue" "cyan" "green" "yellow" "orange" "red")) (global-highlight-parentheses-mode t)) -(electric-pair-mode 1) -(setq electric-pair-preserve-balance t) -(setq electric-pair-skip-self nil) -(setq electric-pair-delete-adjacent-pairs t) +;; (electric-pair-mode 1) +;; (setq electric-pair-preserve-balance t) +;; (setq electric-pair-skip-self nil) +;; (setq electric-pair-delete-adjacent-pairs t) ;; don't skip newline when auto-pairing parenthesis -(setq electric-pair-skip-whitespace-chars '(9 32)) +;; (setq electric-pair-skip-whitespace-chars '(9 32)) ;; in org-mode buffers, do not pair < and > in order not to interfere with org-tempo -(add-hook 'org-mode-hook (lambda () - (setq-local electric-pair-inhibit-predicate - `(lambda (c) - (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c)))))) +;; (add-hook 'org-mode-hook (lambda () +;; (setq-local electric-pair-inhibit-predicate +;; `(lambda (c) +;; (if (char-equal c ?<) t (,electric-pair-inhibit-predicate c)))))) @@ -12912,7 +14150,7 @@ I am not completely sure on electric-pair-mode yet, sometimes it is very helpful
    -

    4.4.19. rainbow-mode

    +

    4.4.23. rainbow-mode

    Complimentary to the delimiters-packages above, this package sets the background color of the delimiters, which makes it easier to see at a glance where we are in a delimiter-tree. @@ -12928,7 +14166,7 @@ Complimentary to the delimiters-packages above, this package sets the background

    -

    4.4.20. Corfu

    +

    4.4.24. Corfu

    -

    4.4.22. rust

    +

    4.4.26. rust

    This sets up rustic-mode with tree-sitter support - there is still one issue to iron out with automatic adding of dependency crates, but everything else works fine now. @@ -13078,7 +14316,7 @@ This sets up rustic-mode with tree-sitter support - there is still one issue to

    -

    4.4.23. Tramp

    +

    4.4.27. Tramp

    Tramp allows for SSH access of files over Emacs. I have no ideas what the options here mean, but this is a recommended configuration that I found (sadly I lost the link). I need to research more what these options really do. @@ -13109,6 +14347,8 @@ Tramp allows for SSH access of files over Emacs. I have no ideas what the option "-o ControlMaster=auto -o ControlPersist=yes")) ) +(setq vterm-tramp-shells '(("ssh" "'sh'"))) + @@ -13116,7 +14356,7 @@ Tramp allows for SSH access of files over Emacs. I have no ideas what the option

    -

    4.4.24. diff-hl

    +

    4.4.28. diff-hl

    This is a simple highlighting utility that uses the margin to visually show the differences since the last git commit. @@ -13138,7 +14378,7 @@ This is a simple highlighting utility that uses the margin to visually show the

    -

    4.4.25. Commenting

    +

    4.4.29. Commenting

    This package allows for swift commenting out and in of code snippets. For some reason, it is a bit broken in my config, as it sometimes comments out too much, sometimes too little, and sometimes it splits lines during commenting. Also, in org-mode when inside a src-block, it often times jumps to the top of the block. @@ -13158,7 +14398,7 @@ Still, this is avery convenient package.

    -

    4.4.26. yasnippet

    +

    4.4.30. yasnippet

    yasnippet allows to define snippets that can be quickly expanded by hitting the TAB key after inputting a keyword. @@ -13244,16 +14484,13 @@ The following block is mostly inspired from -

    4.4.27. eglot

    -
    +
    +

    4.4.31. eglot

    +

    After having tried out lsp-mode and lsp-bridge for a while each, I must say that eglot feels the most clean and fast to me.

    -

    -:CUSTOMID: h:424fbc62-84e2-42c7-a1ca-e43ea04c43e5 -

    @@ -13286,12 +14523,32 @@ After having tried out lsp-mode and lsp-bridge for a w
     
     (defalias 'start-lsp-server #'eglot)
     
    +
    +
    +
    +
    +
    +

    4.4.32. sideline-flymake

    +
    +

    +This brings back warnings and errors on the sideline for eglot; a feature that I have been missing from lsp-mode for a while. +

    + +
    +
    +(use-package sideline-flymake
    +  :hook (flymake-mode . sideline-mode)
    +  :init
    +  (setq sideline-flymake-display-mode 'point) ; 'point to show errors only on point
    +                                              ; 'line to show errors on the current line
    +  (setq sideline-backends-right '(sideline-flymake)))
    +
     
    -

    4.4.28. Breadcrumb

    +

    4.4.33. Breadcrumb

    This simple shows the path to the current file on the top of the buffer - I just think it looks kind of neat, even though it is not extremely useful :) @@ -13300,14 +14557,15 @@ This simple shows the path to the current file on the top of the buffer - I just

     (use-package breadcrumb
    -  :config (breadcrumb-mode))
    +  ;; :config (breadcrumb-mode)
    +  )
     
     
    -

    4.4.29. Prevent breaking of hardlinks

    +

    4.4.34. Prevent breaking of hardlinks

    This setting ensures that hard links are preserved during the backup process, which is useful for maintaining the integrity of files that are linked in multiple locations. @@ -13322,7 +14580,7 @@ This setting ensures that hard links are preserved during the backup process, wh

    -

    4.4.30. Dirvish

    +

    4.4.35. Dirvish

    Dirvish is an improvement upon the dired-framework and has more features like file preview etc. Sadly it has an incompatibility with openwith which is why I have disabled that package. @@ -13386,7 +14644,7 @@ Dirvish is an improvement upon the dired-framework and has more features like fi

    -

    4.4.31. pdf-tools: pdf-viewer and support for dirvish

    +

    4.4.36. pdf-tools: pdf-viewer and support for dirvish

    This enables pdf-previewing in dirvish and gives a much better pdf-viewer than is shipped normally by emacs. @@ -13405,7 +14663,7 @@ This enables pdf-previewing in dirvish and gives a much better pdf-viewer than i

    -

    4.4.32. Jupyter

    +

    4.4.37. Jupyter

    This is a jupyter client. Using it is a bit cumbersome though, so I have not fully explored all features. @@ -13420,7 +14678,7 @@ This is a jupyter client. Using it is a bit cumbersome though, so I have not ful

    -

    4.4.33. undo-tree

    +

    4.4.38. undo-tree

    Base emacs undo logic is very useful, but not easy to understand for me. I prefer undo-tree, which makes switching between branches easier and also allows quickly switching back to a much older state using the visualizer. @@ -13441,7 +14699,7 @@ While we are at it, we are also setting up a persistent undo-file for every file

     (use-package undo-tree
    -  ;; :init (global-undo-tree-mode)
    +  :init (global-undo-tree-mode)
       :bind (:map undo-tree-visualizer-mode-map
                   ("h" . undo-tree-visualize-switch-branch-left)
                   ("l" . undo-tree-visualize-switch-branch-left)
    @@ -13450,16 +14708,16 @@ While we are at it, we are also setting up a persistent undo-file for every file
       :config
       (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo"))))
     
    -(add-hook 'prog-mode-hook 'undo-tree-mode)
    -(add-hook 'text-mode-hook 'undo-tree-mode)
    -(add-hook 'org-mode-hook 'undo-tree-mode)
    -(add-hook 'latex-mode-hook 'undo-tree-mode)
    +;; (add-hook 'prog-mode-hook 'undo-tree-mode)
    +;; (add-hook 'text-mode-hook 'undo-tree-mode)
    +;; (add-hook 'org-mode-hook 'undo-tree-mode)
    +;; (add-hook 'latex-mode-hook 'undo-tree-mode)
     
    -

    4.4.34. Hydra

    +

    4.4.39. Hydra

    Hydra allows for the writing of macro-style functions. I have not yet looked into this all too much, but it seems to be a potent feature. @@ -13496,7 +14754,7 @@ I only wrote this in order to try out hydra; rarely do I really need this. Howev

    -

    4.4.35. External Applications

    +

    4.4.40. External Applications

      @@ -13645,7 +14903,7 @@ This section is here to make Anki usable from within Emacs - an endeavour that I
    -

    4.4.36. Email

    +

    4.4.41. Email

      @@ -13755,7 +15013,7 @@ This adds the simple utility of sending desktop notifications whenever a new mai
    -

    4.4.37. Calendar

    +

    4.4.42. Calendar

    This provides a beautiful calender to emacs. @@ -13771,7 +15029,7 @@ Yes, I am aware that I am exposing my university-calendar to the public here. I :init ;; set org-caldav-sync-initalization (setq swarsel-caldav-synced 0) - (setq org-caldav-url "https://stash.swarsel.win/remote.php/dav/calendars/Swarsele") + (setq org-caldav-url "https://stash.swarsel.win/remote.php/dav/calendars/Swarsel") (setq org-caldav-calendars '((:calendar-id "personal" :inbox "~/Calendars/leon_cal.org"))) @@ -13823,7 +15081,7 @@ Yes, I am aware that I am exposing my university-calendar to the public here. I

    -

    4.4.38. Dashboard: emacs startup screen

    +

    4.4.43. Dashboard: emacs startup screen

    This sets up the dashboard, which is really quite useless. But, it looks cool and makes me happy whenever I start an emacsclient without a file name as argument :) @@ -13895,17 +15153,121 @@ This sets up the dashboard, which is really quite useless. But, it

    -
    -

    4.4.39. ansible

    -
    +
    +

    4.4.44. vterm

    +
    -(use-package ansible
    -    :hook
    -    (yaml-ts-mode . ansible))
    +(use-package vterm
    +    :ensure t)
     
    +(defun sudo-find-file (file-name)
    +"Like find file, but opens the file as root."
    +(interactive "FSudo Find File: ")
    +(let ((tramp-file-name (concat "/sudo::" (expand-file-name file-name))))
    +  (find-file tramp-file-name)))
    +;;; vterm/config.el -*- lexical-binding: t; -*-
     
    +  ;; Original functions overwrites tramp path with a guessed path.
    +  ;; However it breaks if remote fqdn/hostname is not resolvale by local machine
    +  ;; could also break on port forwarding, multihops,
    +  ;; custom protocol such as: docker, vagrant, ...
    +  ;; *if* you try to shell-side configure them.
    +  ;; Easily testable with vagrant ssh port on localhost.
    +  ;; My workflow is to open a tramp dired on / of the remote to get a
    +  ;; "foothold" then open vterms from there.
    +  (defun vterm--get-directory (path)
    +    "[OVERLOADED] Get normalized directory to PATH."
    +    (when path
    +      (let (directory)
    +        (if (string-match "^\\(.*?\\)@\\(.*?\\):\\(.*?\\)$" path)
    +            (progn
    +              (let ((user (match-string 1 path))
    +                    (host (match-string 2 path))
    +                    (dir (match-string 3 path)))
    +                (if (and (string-equal user user-login-name)
    +                         (string-equal host (system-name)))
    +                    (progn
    +                      (when (file-directory-p dir)
    +                        (setq directory (file-name-as-directory dir))))
    +                  (setq directory
    +                        ;; Bellow is what i altered
    +                        (file-name-as-directory (concat (file-remote-p default-directory) dir))))))
    +          (when (file-directory-p path)
    +            (setq directory (file-name-as-directory path))))
    +        directory)))
    +  ;; Injects the payload to the vterm buffer.
    +  (defun me/vterm-load-config ()
    +    "Pass local configuration files to vterm.
     
    +Allows remote vterm to be shell-side configured,
    +without altering remote config.
    +Also adds my personal configuration that does not rely
    +too much on external packages.
    +Prints a reasuring message to proove good faith."
    +    (interactive)
    +    (let (;; Bellow messages to reassure other users that look at history
    +          (reasuring-message (format "Configuring shell of user %s to be emacs comptible"
    +                                     user-full-name))
    +          (reasuring-notice "This action is shell local, it will not affect other shells")
    +          ;; Bellow lies my configuration
    +          (basic-func-script (f-read-text (concat (getenv "HOME")
    +                                                  "/.emacs.d/shells/sources/functions.sh")))
    +          ;; Bellow lies the vterm shell-side configuration
    +          ;; Must be sourced last
    +          (vterm-func-script (f-read-text (concat
    +                                           (file-name-directory (find-library-name "vterm"))
    +                                           "/etc/emacs-vterm-bash.sh"))))
    +      (vterm-insert (format "# START: %s\n" reasuring-message))
    +      (vterm-insert (format "# %s\n" reasuring-notice))
    +      ;; Create one single block in history
    +      (vterm-insert "{\n")
    +      (vterm-insert basic-func-script)
    +      (vterm-insert vterm-func-script)
    +      (vterm-insert "}\n")
    +      ;; End the single block in history
    +      (vterm-insert (format "# %s\n" reasuring-notice))
    +      (vterm-insert (format "# STOP: %s\n" reasuring-message))
    +      )
    +    )
    +
    +  ;; find-file-other-window does not works great on remote:
    +  ;; if given an absolute path on a remote host,
    +  ;; the path will be understood as a local file since no
    +  ;; tramp prefix is present, and bash does not care
    +  ;; about tramp prefixes.
    +  ;; Bellow we solve context before sending it to
    +  ;; ffow
    +  (defun me/vterm--find-file-other-window-wrapper (file)
    +    "Help vterm find a FILE."
    +    (find-file-other-window (me/vterm--ffow-resolver file)))
    +  (defun me/vterm--ffow-resolver (file)
    +    "Help vterm resolve FILE."
    +    (cond
    +     ;; "/sudo::"
    +     ;; doom--sudo-file-path do the trick for us
    +     ((s-starts-with-p "/sudo::" file)
    +       (sudo-find-file
    +        (concat (file-remote-p default-directory)
    +                (substring-no-properties file 7))))
    +     ;; "/" means we want the "Relative root"
    +     ;; try appending the remote prefix if relevent
    +     ((s-starts-with-p "/" file)
    +      (concat (file-remote-p default-directory) file))
    +     ;; we got a relative path
    +     ;; we don't need to help ffow to find it
    +     (t
    +      file)))
    +
    +  ;; The variable vterm-eval-cmds is a SERIOUSLY SENSIBLE variable !
    +  ;; Do not be the guy that adds RCE into their config !
    +
    +  ;; Allow customed ffow to be called from vterm
    +  ;; ffow should be as safe as find-file which is already trusted
    +  ;; we append our resolver that only manipulate strings,
    +  ;; Proove me wrong but i think it's safe.
    +  (add-to-list 'vterm-eval-cmds '("find-file-other-window"
    +                                  me/vterm--find-file-other-window-wrapper))
     
    @@ -13915,7 +15277,7 @@ This sets up the dashboard, which is really quite useless. But, it
    diff --git a/programs/emacs/init.el b/programs/emacs/init.el index 7fdb312..6381f20 100644 --- a/programs/emacs/init.el +++ b/programs/emacs/init.el @@ -157,7 +157,7 @@ create a new one." [C-backspace] #'up-directory) (defun swarsel/org-mode-setup () - (org-indent-mode) + ;; (org-indent-mode) (variable-pitch-mode 1) ;;(auto-fill-mode 0) ;; (setq display-line-numbers-type 'relative @@ -1012,6 +1012,7 @@ create a new one." (push '("conf-unix" . conf-unix) org-src-lang-modes) (setq org-export-with-broken-links 'mark) + (setq org-confirm-babel-evaluate nil) (require 'org-tempo) (add-to-list 'org-structure-template-alist '("sh" . "src shell"))