diff --git a/config/face.jpeg b/config/face.jpeg new file mode 100644 index 00000000..7ad35274 Binary files /dev/null and b/config/face.jpeg differ diff --git a/flake.lock b/flake.lock index 24ac6465..cd0f7b8e 100644 --- a/flake.lock +++ b/flake.lock @@ -766,6 +766,64 @@ "type": "github" } }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable", + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1763030490, + "narHash": "sha256-U1xBvM3vbh7GZyc2ahziMVhi4qQyQ8pRwb9l8jD4ShI=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "7920a7b0553e0bebce825b0d9deb575e26f6f6ac", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1756556321, + "narHash": "sha256-RLD89dfjN0RVO86C/Mot0T7aduCygPGaYbog566F0Qo=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "01be0e65f4eb91a9cd624ac0b76aaeab765c7294", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v25.08", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1763014447, + "narHash": "sha256-nmu7S8J9IJKLQyIkSU8QWYHygrfw76NHGTkcr+bXMX0=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "a52df533c4694b5ed0a04140af60fd26146df911", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, "nix-alien": { "inputs": { "flake-compat": "flake-compat_3", @@ -840,6 +898,22 @@ } }, "nixpkgs-stable": { + "locked": { + "lastModified": 1762756533, + "narHash": "sha256-HiRDeUOD1VLklHeOmaKDzf+8Hb7vSWPVFcWwaTrpm+U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c2448301fb856e351aab33e64c33a3fc8bcf637d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { "locked": { "lastModified": 1762233356, "narHash": "sha256-cGS3lLTYusbEP/IJIWGgnkzIl+FA5xDvtiHyjalGr4k=", @@ -923,6 +997,30 @@ "type": "github" } }, + "noctalia": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "quickshell": [ + "quickshell" + ], + "systems": "systems_5" + }, + "locked": { + "lastModified": 1763040508, + "narHash": "sha256-C0rkHOH6AxEZUYp5NXWepQYjGmsIcO2xEyme6wR0Zyc=", + "owner": "noctalia-dev", + "repo": "noctalia-shell", + "rev": "04439699ae13342510265557c7ba554f0da6ecfa", + "type": "github" + }, + "original": { + "owner": "noctalia-dev", + "repo": "noctalia-shell", + "type": "github" + } + }, "nps": { "inputs": { "flake-compat": "flake-compat_4", @@ -1039,6 +1137,26 @@ "type": "github" } }, + "quickshell": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1761897390, + "narHash": "sha256-er4gYrIoThYLjlsOMTysoRfn67d1Gci+ZpqDrtQxrA0=", + "owner": "quickshell-mirror", + "repo": "quickshell", + "rev": "fc704e6b5d445899a1565955268c91942a4f263f", + "type": "github" + }, + "original": { + "owner": "quickshell-mirror", + "repo": "quickshell", + "type": "github" + } + }, "root": { "inputs": { "devshell": "devshell", @@ -1051,13 +1169,16 @@ "hyprspace": "hyprspace", "impermanence": "impermanence", "lanzaboote": "lanzaboote", + "niri": "niri", "nix-alien": "nix-alien", "nix-flatpak": "nix-flatpak", "nixpkgs": "nixpkgs_3", - "nixpkgs-stable": "nixpkgs-stable", + "nixpkgs-stable": "nixpkgs-stable_2", "nixvim": "nixvim", + "noctalia": "noctalia", "nps": "nps", "nur": "nur", + "quickshell": "quickshell", "sops-nix": "sops-nix", "textfox": "textfox" } @@ -1163,6 +1284,21 @@ "type": "github" } }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "textfox": { "inputs": { "firefox-addons": "firefox-addons", @@ -1224,6 +1360,39 @@ "repo": "xdg-desktop-portal-hyprland", "type": "github" } + }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1755491097, + "narHash": "sha256-m+9tUfsmBeF2Gn4HWa6vSITZ4Gz1eA1F5Kh62B0N4oE=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "388d291e82ffbc73be18169d39470f340707edaa", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.7", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1762747449, + "narHash": "sha256-Z1TKiux8K09a93w4PFDFsj8HFugXNy3iCC3Z8MpR5Rk=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "6338574bc5c036487486acde264f38f39ea15fad", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index c0574d4f..e3b57324 100644 --- a/flake.nix +++ b/flake.nix @@ -49,6 +49,35 @@ # https://github.com/thiagokokada/nix-alien#user-content-nixos-installation-with-flakes # nix-alien.inputs.nixpkgs.follows = "nixpkgs"; + # Niri + niri.url = "github:sodiboo/niri-flake"; + niri.inputs.nixpkgs.follows = "nixpkgs"; + + # Quickshell + quickshell.url = "github:quickshell-mirror/quickshell"; + quickshell.inputs.nixpkgs.follows = "nixpkgs"; + + # Noctalia shell + noctalia.url = "github:noctalia-dev/noctalia-shell"; + noctalia.inputs.nixpkgs.follows = "nixpkgs"; + noctalia.inputs.quickshell.follows = "quickshell"; + + # Caelestia shell + # caelestia.url = "github:caelestia-dots/shell"; + # caelestia.inputs.nixpkgs.follows = "nixpkgs"; + # caelestia.inputs.quickshell.follows = "quickshell"; + # caelestia-cli.url = "github:caelestia-dots/cli"; + # caelestia-cli.inputs.nixpkgs.follows = "nixpkgs"; + + # DankMaterialShell + # dgop.url = "github:AvengeMedia/dgop"; + # dgop.inputs.nixpkgs.follows = "nixpkgs"; + # dms-cli.url = "github:AvengeMedia/danklinux"; + # dms-cli.inputs.nixpkgs.follows = "nixpkgs"; + # dankMaterialShell.url = "github:AvengeMedia/DankMaterialShell"; + # dankMaterialShell.inputs.nixpkgs.follows = "nixpkgs"; + # dankMaterialShell.inputs.dgop.follows = "dgop"; + # Hyprland (use flake so plugins are not built from source) hyprland.url = "github:hyprwm/Hyprland"; hyprland.inputs.nixpkgs.follows = "nixpkgs"; @@ -130,6 +159,7 @@ in [ inputs.devshell.overlays.default inputs.nur.overlays.default + inputs.niri.overlays.niri # inputs.emacs-overlay.overlay # All my own overlays (derivations + modifications) @@ -194,6 +224,7 @@ extraModules = [ inputs.disko.nixosModules.disko + inputs.niri.nixosModules.niri # This also imports the HM module ] ++ commonModules; }; @@ -203,7 +234,9 @@ username = "christoph"; headless = false; extraModules = - [] + [ + inputs.niri.nixosModules.niri + ] ++ commonModules; }; servenix = mylib.nixos.mkNixosConfigWithHomeManagerModule { diff --git a/home/christoph/default.nix b/home/christoph/default.nix index 264a3553..d8d16c72 100644 --- a/home/christoph/default.nix +++ b/home/christoph/default.nix @@ -14,821 +14,839 @@ pkgs, headless, ... -}: -# This is a HM module. -# Because no imports/options/config is defined explicitly, everything is treated as config: -# { inputs, lib, ... }: { ... } gets turned into { inputs, lib, ... }: { config = { ... }; } implicitly. -{ - # Every module is a nix expression, specifically a function { inputs, lib, ... }: { ... }. - # Every module (/function) is called with the same arguments as this module. - # Arguments with matching names are "plugged in" into the right slots, - # the case of different arity is handled by always providing ellipses (...) in module definitions. - imports = [ - # Import the host-specific HM config. - # It will be merged with the main config (like all different modules). - # Settings regarding a specific host (e.g. desktop or laptop) - # should only be made in the host-specific config. - ./${hostname} +}: let + inherit (config.modules) color; +in + # This is a HM module. + # Because no imports/options/config is defined explicitly, everything is treated as config: + # { inputs, lib, ... }: { ... } gets turned into { inputs, lib, ... }: { config = { ... }; } implicitly. + { + # Every module is a nix expression, specifically a function { inputs, lib, ... }: { ... }. + # Every module (/function) is called with the same arguments as this module. + # Arguments with matching names are "plugged in" into the right slots, + # the case of different arity is handled by always providing ellipses (...) in module definitions. + imports = [ + # Import the host-specific HM config. + # It will be merged with the main config (like all different modules). + # Settings regarding a specific host (e.g. desktop or laptop) + # should only be made in the host-specific config. + ./${hostname} - # Import all of my custom HM modules. - ../modules - ]; - - # Enable and configure my custom HM modules. - paths = rec { - nixflake = "${config.home.homeDirectory}/NixFlake"; - dotfiles = "${nixflake}/config"; - }; - - modules = { - beets.enable = !headless; - - btop.enable = true; - - chromium = { - enable = !headless; - google = false; - }; - - color = { - scheme = "catppuccin-mocha"; - font = builtins.head nixosConfig.fonts.fontconfig.defaultFonts.monospace; - wallpaper = "Windows"; - - accent = "mauve"; - accentHl = "pink"; - accentDim = "lavender"; - accentText = "base"; - }; - - docs.enable = !headless; - - firefox = { - enable = !headless; - wayland = true; - vaapi = true; - textfox = true; - disableTabBar = true; - }; - - fish.enable = true; - - git = { - enable = true; - - userName = "Christoph Urlacher"; - userEmail = "christoph.urlacher@protonmail.com"; - signCommits = true; - }; - - hyprland = import ./hyprland.nix {inherit pkgs config headless;}; - hyprpanel.enable = !headless; - kitty.enable = !headless; - lazygit.enable = true; - mpd.enable = !headless; - - neovim = { - enable = true; - alias = true; - neovide = !headless; - }; - - nnn.enable = false; # Use yazi - qutebrowser.enable = !headless; - rmpc.enable = !headless; - - rofi = { - enable = !headless; - }; - - waybar.enable = false; # Use hyprpanel - yazi.enable = true; - zathura.enable = !headless; - }; - - manual = { - manpages.enable = nixosConfig.documentation.enable; - html.enable = false; - }; - - # Make fonts installed through user packages available to applications. - # Also updates the font-cache. - fonts.fontconfig.enable = !headless; - - # This only works when HM is installed as a system module, - # as nixosConfig won't be available otherwise. - xdg = { - enable = true; # This only does xdg path management - mime.enable = nixosConfig.modules.mime.enable; - - mimeApps = { - enable = nixosConfig.modules.mime.enable; - - associations.added = nixosConfig.xdg.mime.addedAssociations; - associations.removed = nixosConfig.xdg.mime.removedAssociations; - defaultApplications = nixosConfig.xdg.mime.defaultApplications; - }; - - portal = { - inherit (nixosConfig.xdg.portal) enable xdgOpenUsePortal config extraPortals; - }; - }; - - home = { - inherit username; # Inherited from flake.nix - - homeDirectory = "/home/${config.home.username}"; - enableNixpkgsReleaseCheck = true; - - # Environment variables - sessionVariables = lib.mkMerge [ - { - LANG = "en_US.UTF-8"; - MANPAGER = "nvim +Man!"; - } - (lib.mkIf (!headless) { - # TERMINAL = "alacritty -o font.size=12"; - TERMINAL = "kitty"; - BROWSER = "firefox"; - - # Enable wayland - XDG_SESSION_TYPE = "wayland"; - QT_QPA_PLATFORM = "wayland"; - NIXOS_OZONE_WL = "1"; - SDL_VIDEODRIVER = "wayland"; - - # Run SSH_ASKPASS as GUI, not TTY for Obsidian git - SSH_ASKPASS_REQUIRE = "prefer"; - - # GTK_IM_MODULE, QT_IM_MODULE, XMODIFIERS are set by HomeManager fcitx5 module - }) + # Import all of my custom HM modules. + ../modules ]; - # Files to generate in the home directory are specified here. - file = lib.mkMerge [ - { - # Because we can't access the absolute path /run/secrets/... we have to symlink. - # This will create a chain of links leading to /run/secrets/... without /nix/store - # containing the secret contents. - ".ssh/id_ed25519".source = - config.lib.file.mkOutOfStoreSymlink - nixosConfig.sops.secrets.ssh-private-key.path; - - ".ssh/id_ed25519.pub".text = "${publicKeys.${username}.ssh}"; - - ".secrets/age/age.pub".text = "${publicKeys.${username}.age}"; - - # The sops config specifies what happens when we call sops edit - ".sops.yaml".text = '' - keys: - - &${username} ${publicKeys.${username}.age} - creation_rules: - - path_regex: secrets.yaml$ - key_groups: - - age: - - *${username} - ''; - - ".config/nix/nix.conf".source = - config.lib.file.mkOutOfStoreSymlink - nixosConfig.sops.templates."nix.conf".path; - } - (lib.mkIf nixosConfig.modules.desktopportal.termfilechooser.enable { - ".config/xdg-desktop-portal-termfilechooser/config".text = '' - [filechooser] - cmd=${pkgs.xdg-desktop-portal-termfilechooser}/share/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh - default_dir=$HOME - env=TERMCMD=kitty --class=file_chooser - open_mode = suggested - save_mode = last - ''; - }) - (lib.mkIf config.modules.git.enable { - ".ssh/allowed_signers".text = "* ${publicKeys.${username}.ssh}"; - }) - (lib.mkIf config.programs.navi.enable { - ".local/share/navi/cheats/christoph.cheat".source = config.lib.file.mkOutOfStoreSymlink "${config.paths.dotfiles}/navi/christoph.cheat"; - }) - (lib.mkIf (!headless) { - # killswitch: 0, 1, 2 (off, on, advanced - still on after reboot) - # netshield: 0, 1, 2 (off, malware, ads+malware+trackers) - ".config/Proton/VPN/settings.json".text = '' - { - "protocol": "wireguard", - "killswitch": 1, - "custom_dns": { - "enabled": false, - "ip_list": [] - }, - "ipv6": true, - "anonymous_crash_reports": false, - "features": { - "netshield": 1, - "moderate_nat": true, - "vpn_accelerator": true, - "port_forwarding": false - } - } - ''; - ".config/Proton/VPN/app-config.json".text = '' - { - "tray_pinned_servers": [ - "DE", - "CH", - "AU" - ], - "connect_at_app_startup": null, - "start_app_minimized": true - } - ''; - }) - ]; - - # Here, custom scripts can be run when activating a HM generation. - # If those scripts contain side-effects, like creating files, - # they must be placed after the "writeBoundary" node in the execution graph. - activation = { - # Example with side-effects: - # linkObsidianLatexSnippets = - # lib.hm.dag.entryAfter ["writeBoundary"] - # (mylib.modules.mkLink "~/NixFlake/config/obsidian/latex_snippets.json" "~/Notes/Obsidian/Chriphost/latex_snippets.json"); + # Enable and configure my custom HM modules. + paths = rec { + nixflake = "${config.home.homeDirectory}/NixFlake"; + dotfiles = "${nixflake}/config"; }; - # Add stuff for your user as you see fit: - # TODO: Make the headless installations smaller - packages = with pkgs; - lib.mkMerge [ - [ - # Shell utils - (ripgrep.override {withPCRE2 = true;}) # fast as fuck - gdu # Alternative to du-dust (I like it better) - duf # Disk usage analyzer (for all disk overview) - sd # Sed alternative - fclones # Duplicate file finder - tealdeer # Very fast tldr (so readable man) - killall - atool # Archive preview - ouch # Unified compression/decompression - ffmpegthumbnailer # Video thumbnails - mediainfo # Media meta information - file # File meta information - unrar # Cooler WinRar - p7zip # Zip stuff - unzip # Unzip stuff - progress # Find coreutils processes and show their progress - tokei # Text file statistics in a project - playerctl # Media player control - pastel # Color tools - nvd # Nix rebuild diff - nix-search-tv # Search nixpkgs, nur, nixos options and homemanager options - nix-tree # Browse the nix store sorted by size (gdu for closures) - nurl # Generate nix fetcher sections based on URLs - python313 # Nicer scripting than bash - binsider # Analyze binaries - lazyjournal # Journalctl viewer - systemctl-tui - restic # Backups + modules = { + beets.enable = !headless; - # Hardware/Software info - pciutils # lspci - mesa-demos # OpenGL info - wayland-utils # wayland-info - clinfo # OpenCL info - vulkan-tools # vulkaninfo - libva-utils # vainfo - vdpauinfo # Video-Decode and Presentation API for Unix info - hwloc # Generate CPU topology diagram - lm_sensors # Readout hardware sensors - acpica-tools # Dump ACPI tables etc. - smartmontools # Disk health - nvme-cli # NVME disk health + btop.enable = true; - # Video/Image/Audio utils - ffmpeg-full # I love ffmpeg (including ffplay) - ffmpeg-normalize # Normalize audio - imagemagick # Convert image (magic) - mp3val # Validate mp3 files - flac # Validate flac files - spotdl + chromium = { + enable = !headless; + google = false; + }; - # Document utils - poppler-utils # pdfunite - graphviz # generate graphs from code - d2 # generate diagrams from code - plantuml # generate diagrams - gnuplot # generate function plots - pdf2svg # extract vector graphics from pdf - pandoc # document converting madness + color = { + scheme = "catppuccin-mocha"; + font = builtins.head nixosConfig.fonts.fontconfig.defaultFonts.monospace; + wallpaper = "Windows"; - # Networking - dig # Make DNS requests - tcpdump # Listen in on TCP traffic - traceroute # "Follow" a packet - gping # ping with graph - curlie # curl a'la httpie - wget # download that shit - dogdns # dns client - rsync # cp on steroids - rclone # Rsync for cloud - httpie # Cool http client - cifs-utils # Mount samba shares - nfs-utils # Mount NFS shares - sshfs # Mount remote directories via SSH + accent = "mauve"; + accentHl = "pink"; + accentDim = "lavender"; + accentText = "base"; + }; - # Run unpatched binaries on NixOS - # Sets NIX_LD_LIBRARY_PATH and NIX_LD variables for nix-ld. - # Usage: "nix-alien-ld -- ". - inputs.nix-alien.packages.${system}.nix-alien + docs.enable = !headless; - # Search nixpkgs - inputs.nps.packages.${system}.default + firefox = { + enable = !headless; + wayland = true; + vaapi = true; + textfox = true; + disableTabBar = true; + }; - # Use NixCommunity binary cache - cachix - ] - (lib.mkIf (!headless) [ - ripdrag # drag & drop from terminal - veracrypt + fish.enable = true; - # Proton - protonvpn-gui - protonmail-bridge-gui + git = { + enable = true; - # GUI stuff - nautilus # Just in case - signal-desktop - anki - font-manager # Previews fonts, but doesn't set them - nextcloud-client - keepassxc - thunderbird # TODO: Email module - obsidian - zotero - zeal # docs browser - helvum - vlc - audacity - ferdium - gparted - tidal-hifi - tidal-dl-ng - picard - handbrake - teamspeak6-client + userName = "Christoph Urlacher"; + userEmail = "christoph.urlacher@protonmail.com"; + signCommits = true; + }; - # Office - kdePackages.wacomtablet # For xournalpp/krita - xournalpp # Write with a pen, like old people - hunspell # I cna't type - hunspellDicts.en_US - hunspellDicts.de_DE - ]) + hyprland = import ./hyprland.nix {inherit pkgs config headless;}; + hyprpanel.enable = !headless; + + kitty.enable = !headless; + lazygit.enable = true; + mpd.enable = !headless; + + niri = { + enable = !headless; + }; + + neovim = { + enable = true; + alias = true; + neovide = !headless; + }; + + nnn.enable = false; # Use yazi + qutebrowser.enable = !headless; + rmpc.enable = !headless; + + rofi = { + enable = !headless; + }; + + waybar.enable = false; # Use hyprpanel + yazi.enable = true; + zathura.enable = !headless; + }; + + manual = { + manpages.enable = nixosConfig.documentation.enable; + html.enable = false; + }; + + # Make fonts installed through user packages available to applications. + # Also updates the font-cache. + fonts.fontconfig.enable = !headless; + + # This only works when HM is installed as a system module, + # as nixosConfig won't be available otherwise. + xdg = { + enable = true; # This only does xdg path management + mime.enable = nixosConfig.modules.mime.enable; + + mimeApps = { + enable = nixosConfig.modules.mime.enable; + + associations.added = nixosConfig.xdg.mime.addedAssociations; + associations.removed = nixosConfig.xdg.mime.removedAssociations; + defaultApplications = nixosConfig.xdg.mime.defaultApplications; + }; + + portal = { + inherit (nixosConfig.xdg.portal) enable xdgOpenUsePortal config extraPortals; + }; + }; + + home = { + inherit username; # Inherited from flake.nix + + homeDirectory = "/home/${config.home.username}"; + enableNixpkgsReleaseCheck = true; + + # Environment variables + sessionVariables = lib.mkMerge [ + { + LANG = "en_US.UTF-8"; + MANPAGER = "nvim +Man!"; + } + (lib.mkIf (!headless) { + # TERMINAL = "alacritty -o font.size=12"; + TERMINAL = "kitty"; + BROWSER = "firefox"; + + # Enable wayland + XDG_SESSION_TYPE = "wayland"; + QT_QPA_PLATFORM = "wayland"; + NIXOS_OZONE_WL = "1"; + SDL_VIDEODRIVER = "wayland"; + + # Run SSH_ASKPASS as GUI, not TTY for Obsidian git + SSH_ASKPASS_REQUIRE = "prefer"; + + # GTK_IM_MODULE, QT_IM_MODULE, XMODIFIERS are set by HomeManager fcitx5 module + }) ]; - }; - # home.file.".options-doc".source = "${pkgs.modules-options-doc}"; + # Files to generate in the home directory are specified here. + file = lib.mkMerge [ + { + # Because we can't access the absolute path /run/secrets/... we have to symlink. + # This will create a chain of links leading to /run/secrets/... without /nix/store + # containing the secret contents. + ".ssh/id_ed25519".source = + config.lib.file.mkOutOfStoreSymlink + nixosConfig.sops.secrets.ssh-private-key.path; - # Packages with extra options managed by HomeManager natively - programs = { - # The home-manager management tool. - # Will only be enabled if HM is installed standalone. - home-manager.enable = true; + ".ssh/id_ed25519.pub".text = "${publicKeys.${username}.ssh}"; - bat = { - enable = true; + ".secrets/age/age.pub".text = "${publicKeys.${username}.age}"; - themes = { - catppuccin-latte = { - src = pkgs.fetchFromGitHub { - owner = "catppuccin"; - repo = "bat"; - rev = "ba4d16880d63e656acced2b7d4e034e4a93f74b1"; - sha256 = "sha256-6WVKQErGdaqb++oaXnY3i6/GuH2FhTgK0v4TN4Y0Wbw="; - }; - file = "Catppuccin-latte.tmTheme"; - }; + # The sops config specifies what happens when we call sops edit + ".sops.yaml".text = '' + keys: + - &${username} ${publicKeys.${username}.age} + creation_rules: + - path_regex: secrets.yaml$ + key_groups: + - age: + - *${username} + ''; + + ".config/nix/nix.conf".source = + config.lib.file.mkOutOfStoreSymlink + nixosConfig.sops.templates."nix.conf".path; + } + (lib.mkIf nixosConfig.modules.desktopportal.termfilechooser.enable { + ".config/xdg-desktop-portal-termfilechooser/config".text = '' + [filechooser] + cmd=${pkgs.xdg-desktop-portal-termfilechooser}/share/xdg-desktop-portal-termfilechooser/yazi-wrapper.sh + default_dir=$HOME + env=TERMCMD=kitty --class=file_chooser + open_mode = suggested + save_mode = last + ''; + }) + (lib.mkIf config.modules.git.enable { + ".ssh/allowed_signers".text = "* ${publicKeys.${username}.ssh}"; + }) + (lib.mkIf config.programs.navi.enable { + ".local/share/navi/cheats/christoph.cheat".source = config.lib.file.mkOutOfStoreSymlink "${config.paths.dotfiles}/navi/christoph.cheat"; + }) + (lib.mkIf (!headless) { + # killswitch: 0, 1, 2 (off, on, advanced - still on after reboot) + # netshield: 0, 1, 2 (off, malware, ads+malware+trackers) + ".config/Proton/VPN/settings.json".text = '' + { + "protocol": "wireguard", + "killswitch": 1, + "custom_dns": { + "enabled": false, + "ip_list": [] + }, + "ipv6": true, + "anonymous_crash_reports": false, + "features": { + "netshield": 1, + "moderate_nat": true, + "vpn_accelerator": true, + "port_forwarding": false + } + } + ''; + ".config/Proton/VPN/app-config.json".text = '' + { + "tray_pinned_servers": [ + "DE", + "CH", + "AU" + ], + "connect_at_app_startup": null, + "start_app_minimized": true + } + ''; + }) + ]; + + # Here, custom scripts can be run when activating a HM generation. + # If those scripts contain side-effects, like creating files, + # they must be placed after the "writeBoundary" node in the execution graph. + activation = { + # Example with side-effects: + # linkObsidianLatexSnippets = + # lib.hm.dag.entryAfter ["writeBoundary"] + # (mylib.modules.mkLink "~/NixFlake/config/obsidian/latex_snippets.json" "~/Notes/Obsidian/Chriphost/latex_snippets.json"); }; - config = { - theme = "catppuccin-latte"; - }; + # Add stuff for your user as you see fit: + # TODO: Make the headless installations smaller + packages = with pkgs; + lib.mkMerge [ + [ + # Shell utils + (ripgrep.override {withPCRE2 = true;}) # fast as fuck + gdu # Alternative to du-dust (I like it better) + duf # Disk usage analyzer (for all disk overview) + sd # Sed alternative + fclones # Duplicate file finder + tealdeer # Very fast tldr (so readable man) + killall + atool # Archive preview + ouch # Unified compression/decompression + ffmpegthumbnailer # Video thumbnails + mediainfo # Media meta information + file # File meta information + unrar # Cooler WinRar + p7zip # Zip stuff + unzip # Unzip stuff + progress # Find coreutils processes and show their progress + tokei # Text file statistics in a project + playerctl # Media player control + pastel # Color tools + nvd # Nix rebuild diff + nix-search-tv # Search nixpkgs, nur, nixos options and homemanager options + nix-tree # Browse the nix store sorted by size (gdu for closures) + nurl # Generate nix fetcher sections based on URLs + python313 # Nicer scripting than bash + binsider # Analyze binaries + lazyjournal # Journalctl viewer + systemctl-tui + restic # Backups + + # Hardware/Software info + pciutils # lspci + mesa-demos # OpenGL info + wayland-utils # wayland-info + clinfo # OpenCL info + vulkan-tools # vulkaninfo + libva-utils # vainfo + vdpauinfo # Video-Decode and Presentation API for Unix info + hwloc # Generate CPU topology diagram + lm_sensors # Readout hardware sensors + acpica-tools # Dump ACPI tables etc. + smartmontools # Disk health + nvme-cli # NVME disk health + + # Video/Image/Audio utils + ffmpeg-full # I love ffmpeg (including ffplay) + ffmpeg-normalize # Normalize audio + imagemagick # Convert image (magic) + mp3val # Validate mp3 files + flac # Validate flac files + spotdl + + # Document utils + poppler-utils # pdfunite + graphviz # generate graphs from code + d2 # generate diagrams from code + plantuml # generate diagrams + gnuplot # generate function plots + pdf2svg # extract vector graphics from pdf + pandoc # document converting madness + + # Networking + dig # Make DNS requests + tcpdump # Listen in on TCP traffic + traceroute # "Follow" a packet + gping # ping with graph + curlie # curl a'la httpie + wget # download that shit + dogdns # dns client + rsync # cp on steroids + rclone # Rsync for cloud + httpie # Cool http client + cifs-utils # Mount samba shares + nfs-utils # Mount NFS shares + sshfs # Mount remote directories via SSH + + # Run unpatched binaries on NixOS + # Sets NIX_LD_LIBRARY_PATH and NIX_LD variables for nix-ld. + # Usage: "nix-alien-ld -- ". + inputs.nix-alien.packages.${system}.nix-alien + + # Search nixpkgs + inputs.nps.packages.${system}.default + + # Use NixCommunity binary cache + cachix + ] + (lib.mkIf (!headless) [ + ripdrag # drag & drop from terminal + veracrypt + + # Proton + protonvpn-gui + protonmail-bridge-gui + + # GUI stuff + nautilus # Just in case + signal-desktop + anki + font-manager # Previews fonts, but doesn't set them + nextcloud-client + keepassxc + thunderbird # TODO: Email module + obsidian + zotero + zeal # docs browser + helvum + vlc + audacity + ferdium + gparted + tidal-hifi + tidal-dl-ng + picard + handbrake + teamspeak6-client + + # Office + kdePackages.wacomtablet # For xournalpp/krita + xournalpp # Write with a pen, like old people + hunspell # I cna't type + hunspellDicts.en_US + hunspellDicts.de_DE + ]) + ]; }; - cava = { - enable = !headless; + # home.file.".options-doc".source = "${pkgs.modules-options-doc}"; - settings = { - general = { - framerate = 60; # default 60 - autosens = 1; # default 1 - sensitivity = 100; # default 100 - lower_cutoff_freq = 50; # not passed to cava if not provided - higher_cutoff_freq = 10000; # not passed to cava if not provided - }; + # Packages with extra options managed by HomeManager natively + programs = { + # The home-manager management tool. + # Will only be enabled if HM is installed standalone. + home-manager.enable = true; - smoothing = { - noise_reduction = 77; # default 77 - monstercat = false; # default false - waves = false; # default false - }; + bat = { + enable = true; - color = let - color = config.modules.color; - in { - # https://github.com/catppuccin/cava/blob/main/themes/latte-transparent.cava - gradient = 1; - - gradient_color_1 = "'${color.hexS.teal}'"; - gradient_color_2 = "'${color.hexS.sky}'"; - gradient_color_3 = "'${color.hexS.sapphire}'"; - gradient_color_4 = "'${color.hexS.blue}'"; - gradient_color_5 = "'${color.hexS.mauve}'"; - gradient_color_6 = "'${color.hexS.pink}'"; - gradient_color_7 = "'${color.hexS.maroon}'"; - gradient_color_8 = "'${color.hexS.red}'"; - }; - }; - }; - - direnv = { - enable = true; - nix-direnv.enable = true; - }; - - eza = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - }; - - # TODO: Module - fastfetch = { - enable = true; - - settings = { - logo = { - padding = { - top = 3; - left = 1; - right = 2; + themes = { + catppuccin-latte = { + src = pkgs.fetchFromGitHub { + owner = "catppuccin"; + repo = "bat"; + rev = "ba4d16880d63e656acced2b7d4e034e4a93f74b1"; + sha256 = "sha256-6WVKQErGdaqb++oaXnY3i6/GuH2FhTgK0v4TN4Y0Wbw="; + }; + file = "Catppuccin-latte.tmTheme"; }; }; - display = { - separator = ""; - key.width = 17; + config = { + theme = "catppuccin-latte"; }; + }; - # Box Drawing: ╭ ─ ╮ ╰ ╯ │ - modules = [ - # Title - { - type = "title"; - format = "{#1}╭─── {#}{user-name-colored}"; - } + cava = { + enable = !headless; - # System Information - { - type = "custom"; - format = "{#1}│ {#}System Information"; - } - { - type = "os"; - key = "{#separator}│ {#keys}󰍹 OS"; - } - { - type = "kernel"; - key = "{#separator}│ {#keys}󰒋 Kernel"; - } - { - type = "bootmgr"; - key = "{#separator}│ {#keys}󰒋 BootMGR"; - } - { - type = "uptime"; - key = "{#separator}│ {#keys}󰅐 Uptime"; - } - { - type = "packages"; - key = "{#separator}│ {#keys}󰏖 Packages"; - # format = "{all}"; - } - { - type = "custom"; - format = "{#1}│"; - } + settings = { + general = { + framerate = 60; # default 60 + autosens = 1; # default 1 + sensitivity = 100; # default 100 + lower_cutoff_freq = 50; # not passed to cava if not provided + higher_cutoff_freq = 10000; # not passed to cava if not provided + }; - # Desktop Environment - { - type = "custom"; - format = "{#1}│ {#}Desktop Environment"; - } - { - type = "de"; - key = "{#separator}│ {#keys}󰧨 DE"; - } - { - type = "wm"; - key = "{#separator}│ {#keys}󱂬 WM"; - } - { - type = "wmtheme"; - key = "{#separator}│ {#keys}󰉼 Theme"; - } - { - type = "display"; - key = "{#separator}│ {#keys}󰹑 Resolution"; - } - { - type = "shell"; - key = "{#separator}│ {#keys}󰞷 Shell"; - } - { - type = "terminalfont"; - key = "{#separator}│ {#keys}󰛖 Font"; - } - { - type = "icons"; - key = "{#separator}│ {#keys} Icons"; - } - { - type = "cursor"; - key = "{#separator}│ {#keys}󰆽 Cursor"; - } - { - type = "custom"; - format = "{#1}│"; - } + smoothing = { + noise_reduction = 77; # default 77 + monstercat = false; # default false + waves = false; # default false + }; - # Hardware Information - { - type = "custom"; - format = "{#1}│ {#}Hardware Information"; - } - { - type = "board"; - key = "{#separator}│ {#keys} Board"; - } - { - type = "cpu"; - key = "{#separator}│ {#keys}󰻠 CPU"; - } - { - type = "gpu"; - key = "{#separator}│ {#keys}󰢮 GPU"; - } - { - type = "memory"; - key = "{#separator}│ {#keys}󰍛 Memory"; - } - # { - # type = "disk"; - # key = "{#separator}│ {#keys}󰋊 Disk (/)"; - # folders = "/"; - # } - # { - # type = "disk"; - # key = "{#separator}│ {#keys}󰋊 Disk (~/Games)"; - # folders = "/home/christoph/Games"; - # } - { - type = "btrfs"; - key = "{#separator}│ {#keys}󰋊 BTRFS"; - } - { - type = "custom"; - format = "{#1}│"; - } + color = { + # https://github.com/catppuccin/cava/blob/main/themes/latte-transparent.cava + gradient = 1; - # Colors Footer + gradient_color_1 = "'${color.hexS.teal}'"; + gradient_color_2 = "'${color.hexS.sky}'"; + gradient_color_3 = "'${color.hexS.sapphire}'"; + gradient_color_4 = "'${color.hexS.blue}'"; + gradient_color_5 = "'${color.hexS.mauve}'"; + gradient_color_6 = "'${color.hexS.pink}'"; + gradient_color_7 = "'${color.hexS.maroon}'"; + gradient_color_8 = "'${color.hexS.red}'"; + }; + }; + }; + + direnv = { + enable = true; + nix-direnv.enable = true; + }; + + eza = { + enable = true; + enableFishIntegration = config.modules.fish.enable; + }; + + # TODO: Module + fastfetch = { + enable = true; + + settings = { + logo = { + padding = { + top = 3; + left = 1; + right = 2; + }; + }; + + display = { + separator = ""; + key.width = 17; + }; + + # Box Drawing: ╭ ─ ╮ ╰ ╯ │ + modules = [ + # Title + { + type = "title"; + format = "{#1}╭─── {#}{user-name-colored}"; + } + + # System Information + { + type = "custom"; + format = "{#1}│ {#}System Information"; + } + { + type = "os"; + key = "{#separator}│ {#keys}󰍹 OS"; + } + { + type = "kernel"; + key = "{#separator}│ {#keys}󰒋 Kernel"; + } + { + type = "bootmgr"; + key = "{#separator}│ {#keys}󰒋 BootMGR"; + } + { + type = "uptime"; + key = "{#separator}│ {#keys}󰅐 Uptime"; + } + { + type = "packages"; + key = "{#separator}│ {#keys}󰏖 Packages"; + # format = "{all}"; + } + { + type = "custom"; + format = "{#1}│"; + } + + # Desktop Environment + { + type = "custom"; + format = "{#1}│ {#}Desktop Environment"; + } + { + type = "de"; + key = "{#separator}│ {#keys}󰧨 DE"; + } + { + type = "wm"; + key = "{#separator}│ {#keys}󱂬 WM"; + } + { + type = "wmtheme"; + key = "{#separator}│ {#keys}󰉼 Theme"; + } + { + type = "display"; + key = "{#separator}│ {#keys}󰹑 Resolution"; + } + { + type = "shell"; + key = "{#separator}│ {#keys}󰞷 Shell"; + } + { + type = "terminalfont"; + key = "{#separator}│ {#keys}󰛖 Font"; + } + { + type = "icons"; + key = "{#separator}│ {#keys} Icons"; + } + { + type = "cursor"; + key = "{#separator}│ {#keys}󰆽 Cursor"; + } + { + type = "custom"; + format = "{#1}│"; + } + + # Hardware Information + { + type = "custom"; + format = "{#1}│ {#}Hardware Information"; + } + { + type = "board"; + key = "{#separator}│ {#keys} Board"; + } + { + type = "cpu"; + key = "{#separator}│ {#keys}󰻠 CPU"; + } + { + type = "gpu"; + key = "{#separator}│ {#keys}󰢮 GPU"; + } + { + type = "memory"; + key = "{#separator}│ {#keys}󰍛 Memory"; + } + # { + # type = "disk"; + # key = "{#separator}│ {#keys}󰋊 Disk (/)"; + # folders = "/"; + # } + # { + # type = "disk"; + # key = "{#separator}│ {#keys}󰋊 Disk (~/Games)"; + # folders = "/home/christoph/Games"; + # } + { + type = "btrfs"; + key = "{#separator}│ {#keys}󰋊 BTRFS"; + } + { + type = "custom"; + format = "{#1}│"; + } + + # Colors Footer + { + type = "colors"; + key = "{#separator}╰─── {#1}"; + keyWidth = 6; + symbol = "circle"; + } + ]; + }; + }; + + fd.enable = true; + + fzf = { + enable = true; + enableFishIntegration = config.modules.fish.enable; + }; + + imv = { + enable = !headless; + settings = { + options = { + background = "${color.hex.base}"; + overlay = true; + overlay_font = "${color.font}:12"; + overlay_background_color = "${color.hex.accent}"; + overlay_text_color = "${color.hex.accentText}"; + }; + }; + }; + + keychain = { + enable = true; + enableFishIntegration = config.modules.fish.enable; + enableXsessionIntegration = !headless; + keys = ["id_ed25519"]; + }; + + mpv = { + enable = false; + config = { + gpu-context = "wayland"; + }; + }; + + navi = { + enable = true; + enableFishIntegration = config.modules.fish.enable; + }; + + nix-index = { + enable = true; + enableFishIntegration = config.modules.fish.enable; + }; + + nushell.enable = false; + + # spicetify = let + # spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system}; + # in { + # enable = true; + # + # # https://github.com/catppuccin/spicetify + # theme = spicePkgs.themes.catppuccin; + # colorScheme = "mocha"; + # + # wayland = true; + # + # enabledExtensions = with spicePkgs.extensions; [ + # adblock + # hidePodcasts + # oneko # cat + # ]; + # # enabledCustomApps = with spicePkgs.apps; []; + # enabledSnippets = with spicePkgs.snippets; [ + # rotatingCoverart + # pointer + # ]; + # }; + + ssh = { + enable = true; + enableDefaultConfig = false; + + matchBlocks = { + "*" = { + forwardAgent = false; + addKeysToAgent = "no"; + compression = true; + serverAliveInterval = 0; + serverAliveCountMax = 3; + hashKnownHosts = false; + userKnownHostsFile = "~/.ssh/known_hosts"; + controlMaster = "no"; + controlPath = "~/.ssh/master-%r@%n:%p"; + controlPersist = "no"; + }; + "nixinator" = { + user = "christoph"; + hostname = "192.168.86.50"; + }; + "servenix" = { + user = "christoph"; + hostname = "local.chriphost.de"; + }; + "thinknix" = { + user = "christoph"; + hostname = "think.chriphost.de"; + }; + "vps" = { + user = "root"; + hostname = "vps.chriphost.de"; + }; + }; + }; + + tmux = { + enable = false; + + clock24 = true; + escapeTime = 0; # Delay after pressing escape + # keyMode = "vi"; + terminal = "xterm-256color"; + + plugins = with pkgs; [ { - type = "colors"; - key = "{#separator}╰─── {#1}"; - keyWidth = 6; - symbol = "circle"; + plugin = tmuxPlugins.catppuccin; + extraConfig = '' + set -g @plugin 'catppuccin/tmux' + set -g @catppuccin_flavour 'latte' # or frappe, macchiato, mocha + ''; } ]; + + extraConfig = '' + set -g default-terminal "xterm-256color" + set-option -ga terminal-overrides ",xterm-256color:Tc" + ''; }; - }; - fd.enable = true; + yt-dlp.enable = true; - fzf = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - }; - - keychain = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - enableXsessionIntegration = !headless; - keys = ["id_ed25519"]; - }; - - mpv = { - enable = false; - config = { - gpu-context = "wayland"; - }; - }; - - navi = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - }; - - nix-index = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - }; - - nushell.enable = false; - - # spicetify = let - # spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system}; - # in { - # enable = true; - # - # # https://github.com/catppuccin/spicetify - # theme = spicePkgs.themes.catppuccin; - # colorScheme = "mocha"; - # - # wayland = true; - # - # enabledExtensions = with spicePkgs.extensions; [ - # adblock - # hidePodcasts - # oneko # cat - # ]; - # # enabledCustomApps = with spicePkgs.apps; []; - # enabledSnippets = with spicePkgs.snippets; [ - # rotatingCoverart - # pointer - # ]; - # }; - - ssh = { - enable = true; - enableDefaultConfig = false; - - matchBlocks = { - "*" = { - forwardAgent = false; - addKeysToAgent = "no"; - compression = true; - serverAliveInterval = 0; - serverAliveCountMax = 3; - hashKnownHosts = false; - userKnownHostsFile = "~/.ssh/known_hosts"; - controlMaster = "no"; - controlPath = "~/.ssh/master-%r@%n:%p"; - controlPersist = "no"; - }; - "nixinator" = { - user = "christoph"; - hostname = "192.168.86.50"; - }; - "servenix" = { - user = "christoph"; - hostname = "local.chriphost.de"; - }; - "thinknix" = { - user = "christoph"; - hostname = "think.chriphost.de"; - }; - "vps" = { - user = "root"; - hostname = "vps.chriphost.de"; - }; - }; - }; - - tmux = { - enable = false; - - clock24 = true; - escapeTime = 0; # Delay after pressing escape - # keyMode = "vi"; - terminal = "xterm-256color"; - - plugins = with pkgs; [ - { - plugin = tmuxPlugins.catppuccin; - extraConfig = '' - set -g @plugin 'catppuccin/tmux' - set -g @catppuccin_flavour 'latte' # or frappe, macchiato, mocha - ''; - } - ]; - - extraConfig = '' - set -g default-terminal "xterm-256color" - set-option -ga terminal-overrides ",xterm-256color:Tc" - ''; - }; - - yt-dlp.enable = true; - - zoxide = { - enable = true; - enableFishIntegration = config.modules.fish.enable; - }; - }; - - services = { - kdeconnect = { - enable = nixosConfig.programs.kdeconnect.enable; # Only the system package sets up the firewall - indicator = nixosConfig.programs.kdeconnect.enable; - }; - - flatpak = lib.mkIf nixosConfig.services.flatpak.enable { - # FlatHub stable is only added by default if no custom remotes are specified - remotes = lib.mkOptionDefault [ - { - name = "flathub"; - location = "https://flathub.org/repo/flathub.flatpakrepo"; - } - { - name = "flathub-beta"; - location = "https://flathub.org/beta-repo/flathub-beta.flatpakrepo"; - } - ]; - - packages = lib.mkMerge [ - [] - (lib.mkIf (!headless) [ - "com.github.tchx84.Flatseal" - - # "com.spotify.Client" # Don't need this when spicetify is enabled - - "com.discordapp.Discord" - # "com.discordapp.DiscordCanary" - - # "com.google.Chrome" - # "md.obsidian.Obsidian" - # "io.anytype.anytype" - ]) - ]; - - uninstallUnmanaged = true; - uninstallUnused = true; - - update.auto = { + zoxide = { enable = true; - onCalendar = "daily"; # Default value: weekly + enableFishIntegration = config.modules.fish.enable; + }; + }; + + services = { + kdeconnect = { + enable = nixosConfig.programs.kdeconnect.enable; # Only the system package sets up the firewall + indicator = nixosConfig.programs.kdeconnect.enable; }; - overrides = { - global = { - # Force Wayland by default - # Context.sockets = ["wayland" "!x11" "!fallback-x11"]; # NOTE: Makes discord + steam crash + flatpak = lib.mkIf nixosConfig.services.flatpak.enable { + # FlatHub stable is only added by default if no custom remotes are specified + remotes = lib.mkOptionDefault [ + { + name = "flathub"; + location = "https://flathub.org/repo/flathub.flatpakrepo"; + } + { + name = "flathub-beta"; + location = "https://flathub.org/beta-repo/flathub-beta.flatpakrepo"; + } + ]; - Context.filesystems = ["/nix/store:ro"]; + packages = lib.mkMerge [ + [] + (lib.mkIf (!headless) [ + "com.github.tchx84.Flatseal" - Environment = { - # Fix un-themed cursor in some Wayland apps - XCURSOR_PATH = "/run/host/user-share/icons:/run/host/share/icons"; + # "com.spotify.Client" # Don't need this when spicetify is enabled - # Force correct theme for some GTK apps - GTK_THEME = "Adwaita:light"; + "com.discordapp.Discord" + # "com.discordapp.DiscordCanary" + + # "com.google.Chrome" + # "md.obsidian.Obsidian" + # "io.anytype.anytype" + ]) + ]; + + uninstallUnmanaged = true; + uninstallUnused = true; + + update.auto = { + enable = true; + onCalendar = "daily"; # Default value: weekly + }; + + overrides = { + global = { + # Force Wayland by default + # Context.sockets = ["wayland" "!x11" "!fallback-x11"]; # NOTE: Makes discord + steam crash + + Context.filesystems = ["/nix/store:ro"]; + + Environment = { + # Fix un-themed cursor in some Wayland apps + XCURSOR_PATH = "/run/host/user-share/icons:/run/host/share/icons"; + + # Force correct theme for some GTK apps + GTK_THEME = "Adwaita:light"; + }; + }; + + "io.anytype.anytype".Context = { + filesystems = [ + "${config.home.homeDirectory}" + ]; + }; + + "com.discordapp.Discord".Context = { + filesystems = [ + "${config.home.homeDirectory}" + ]; }; }; - - "io.anytype.anytype".Context = { - filesystems = [ - "${config.home.homeDirectory}" - ]; - }; - - "com.discordapp.Discord".Context = { - filesystems = [ - "${config.home.homeDirectory}" - ]; - }; }; }; - }; - systemd = { - user = { - # TODO: This has been deprecated and replaced with a bad alternative in a stupid HM update - # tmpfiles.rules = lib.mkMerge [ - # [] - # (lib.mkIf (mylib.modules.contains - # config.services.flatpak.packages - # "com.discordapp.Discord") [ - # # Fix Discord rich presence for Flatpak - # "L %t/discord-ipc-0 - - - - app/com.discordapp.Discord/discord-ipc-0" - # ]) - # (lib.mkIf (mylib.modules.contains - # config.services.flatpak.packages - # "com.discordapp.DiscordCanary") [ - # # Fix Discord rich presence for Flatpak - # "L %t/discord-ipc-0 - - - - app/com.discordapp.DiscordCanary/discord-ipc-0" - # ]) - # ]; + systemd = { + user = { + # TODO: This has been deprecated and replaced with a bad alternative in a stupid HM update + # tmpfiles.rules = lib.mkMerge [ + # [] + # (lib.mkIf (mylib.modules.contains + # config.services.flatpak.packages + # "com.discordapp.Discord") [ + # # Fix Discord rich presence for Flatpak + # "L %t/discord-ipc-0 - - - - app/com.discordapp.Discord/discord-ipc-0" + # ]) + # (lib.mkIf (mylib.modules.contains + # config.services.flatpak.packages + # "com.discordapp.DiscordCanary") [ + # # Fix Discord rich presence for Flatpak + # "L %t/discord-ipc-0 - - - - app/com.discordapp.DiscordCanary/discord-ipc-0" + # ]) + # ]; - # Nicely reload system units when changing configs - startServices = "sd-switch"; + # Nicely reload system units when changing configs + startServices = "sd-switch"; + }; }; - }; -} + } diff --git a/home/modules/default.nix b/home/modules/default.nix index 3a1b6653..21689f38 100644 --- a/home/modules/default.nix +++ b/home/modules/default.nix @@ -18,6 +18,7 @@ ./lazygit ./mpd ./neovim + ./niri ./nnn ./paths ./qutebrowser @@ -31,6 +32,10 @@ inputs.nix-flatpak.homeManagerModules.nix-flatpak inputs.nixvim.homeModules.nixvim inputs.textfox.homeManagerModules.default + # inputs.niri.homeModules.niri # Imported by system module + inputs.noctalia.homeModules.default + # inputs.dankMaterialShell.homeModules.dankMaterialShell.default + # inputs.dankMaterialShell.homeModules.dankMaterialShell.niri # NOTE: Do NOT use this, use the system module (the HM module has to rely on fuse) # inputs.impermanence.homeManagerModules.impermanence diff --git a/home/modules/niri/default.nix b/home/modules/niri/default.nix new file mode 100644 index 00000000..d503c222 --- /dev/null +++ b/home/modules/niri/default.nix @@ -0,0 +1,509 @@ +{ + config, + nixosConfig, + lib, + mylib, + pkgs, + ... +}: let + inherit (config.modules) niri color; +in { + options.modules.niri = import ./options.nix {inherit lib mylib;}; + + config = lib.mkIf niri.enable { + assertions = [ + { + assertion = nixosConfig.programs.niri.enable; + message = "Can't enable Niri module with Niri disabled!"; + } + ]; + + home = { + packages = with pkgs; [ + xwayland-satellite + ncpamixer # Audio control + + nautilus # Fallback file chooser used by xdg-desktop-portal-gnome + + # In case we fallback to the default config + alacritty + fuzzel + ]; + }; + + programs = { + noctalia-shell = import ./noctalia.nix {inherit color;}; + + niri = { + # enable = true; # Enabled in system module + + settings = { + input = { + focus-follows-mouse = { + enable = true; + max-scroll-amount = "0%"; # Skip partial windows that would scroll the viewport on focus + }; + + keyboard = { + xkb = { + layout = "us"; + variant = "altgr-intl"; + options = "nodeadkeys"; + }; + }; + + touchpad = { + click-method = "clickfinger"; + tap = true; + drag = true; + dwt = true; + natural-scroll = true; + scroll-method = "two-finger"; + }; + }; + + hotkey-overlay = { + hide-not-bound = true; + skip-at-startup = true; + }; + + prefer-no-csd = true; # Disable client-side decorations (e.g. window titlebars) + + spawn-at-startup = [ + {argv = ["noctalia-shell"];} + {argv = ["kitty" "--hold" "fastfetch"];} + {argv = ["zeal"];} + {argv = ["nextcloud --background"];} + {argv = ["protonvpn-app"];} + {argv = ["keepassxc"];} + {argv = ["fcitx5"];} + + # TODO: On certain workspaces + # {argv = ["ferdium"];} + # {argv = ["kitty --title=Btop btop"];} + # {argv = ["kitty --title=Rmpc rmpc"];} + ]; + + workspaces = { + "1" = {open-on-output = "DP-1";}; + "2" = {open-on-output = "DP-1";}; + "3" = {open-on-output = "DP-1";}; + "4" = {open-on-output = "DP-1";}; + "5" = {open-on-output = "DP-1";}; + "6" = {open-on-output = "DP-1";}; + "7" = {open-on-output = "DP-1";}; + "8" = {open-on-output = "DP-1";}; + "9" = {open-on-output = "DP-1";}; + "10" = {open-on-output = "DP-2";}; + }; + + outputs = { + "DP-1" = { + focus-at-startup = true; + mode = { + width = 3440; + height = 1440; + refresh = 165.0; + }; + position = { + x = 1920; + y = 0; + }; + }; + "DP-2" = { + focus-at-startup = false; + mode = { + width = 1920; + height = 1080; + refresh = 60.0; + }; + position = { + x = 0; + y = 0; + }; + }; + }; + + cursor = { + hide-when-typing = true; + theme = "Bibata-Modern-Classic"; + size = 24; + }; + + layout = { + # This border is drawn INSIDE the window + border = { + enable = true; + width = 2; + active = {color = color.hex.accent;}; + inactive = {color = color.hex.base;}; + }; + + # This border is drawn OUTSIDE of the focused window + focus-ring = { + enable = false; + }; + + # Hint where a dragged window will be inserted + insert-hint = { + enable = true; + display = {color = color.hex.accentDim;}; + }; + + always-center-single-column = false; + + # Gaps between windows + gaps = 8; + + # Gaps at screen borders + struts = { + # left = 8; + # right = 8; + top = 4; # Somehow the bar eclusivity doesn't work as expected + bottom = 2; + }; + }; + + gestures = { + hot-corners = {enable = false;}; + }; + + window-rules = [ + # Rules for all windows + { + clip-to-geometry = true; + geometry-corner-radius = { + bottom-left = 8.0; + bottom-right = 8.0; + top-left = 8.0; + top-right = 8.0; + }; + } + + # Assign to workspaces + { + matches = [{app-id = "Zotero";}]; + open-on-workspace = "2"; + } + { + matches = [{app-id = "neovide";}]; + open-on-workspace = "2"; + } + { + matches = [{app-id = "code-url-handler";}]; + open-on-workspace = "2"; + } + { + matches = [{app-id = "obsidian";}]; + open-on-workspace = "3"; + } + { + matches = [{app-id = "firefox";}]; + open-on-workspace = "4"; + } + { + matches = [{app-id = "Google-chrome";}]; + open-on-workspace = "4"; + } + { + matches = [{app-id = "chromium-browser";}]; + open-on-workspace = "4"; + } + { + matches = [{app-id = "org.qutebrowser.qutebrowser";}]; + open-on-workspace = "4"; + } + { + matches = [{app-id = "steam";}]; + open-on-workspace = "5"; + } + { + matches = [{app-id = "steam_app_(.+)";}]; + open-on-workspace = "6"; + } + { + matches = [{app-id = "signal";}]; + open-on-workspace = "7"; + } + { + matches = [{app-id = "discord";}]; + open-on-workspace = "9"; + } + ]; + + layer-rules = [ + { + # Set the overview wallpaper on the backdrop. + matches = [{namespace = "^noctalia-overview*";}]; + place-within-backdrop = true; + } + ]; + + debug = { + # Allows notification actions and window activation from Noctalia. + honor-xdg-activation-with-invalid-serial = []; + }; + + # TODO: Only start hypr... stuff with hyprland, not systemd (hypridle, hyprpaper currently) + + # TODO: Move values to config option and set in home/christoph/niri.nix + binds = with config.lib.niri.actions; { + # Applications + "Mod+T" = { + action = spawn "kitty"; + hotkey-overlay = {title = "Spawn Kitty.";}; + }; + "Mod+E" = { + action = spawn "kitty" "--title=Yazi" "yazi"; + hotkey-overlay = {title = "Spawn Yazi.";}; + }; + "Mod+B" = { + action = spawn "kitty" "--title=Btop" "btop"; + hotkey-overlay = {title = "Spawn Btop.";}; + }; + "Mod+R" = { + action = spawn "kitty" "--title=Rmpc" "rmpc"; + hotkey-overlay = {title = "Spawn Rmpc.";}; + }; + "Mod+N" = { + action = spawn "neovide"; + hotkey-overlay = {title = "Spawn Neovide.";}; + }; + "Mod+Ctrl+N" = { + action = spawn "kitty" "--title=Navi" "navi"; + hotkey-overlay = {title = "Call Navi for help.";}; + }; + "Mod+Shift+N" = { + action = spawn "neovide" "${config.paths.dotfiles}/navi/christoph.cheat"; + hotkey-overlay = {title = "Edit the Navi cheats.";}; + }; + "Mod+Shift+F" = { + action = spawn "neovide" "${config.paths.dotfiles}/flake.nix"; + hotkey-overlay = {title = "Edit the NixFlake.";}; + }; + + # Noctalia + "Mod+A" = { + action = spawn "noctalia-shell" "ipc" "call" "launcher" "toggle"; + hotkey-overlay = {title = "Toggle the application launcher.";}; + }; + "Mod+Ctrl+L" = { + action = spawn "noctalia-shell" "ipc" "call" "lockScreen" "lock"; + hotkey-overlay = {title = "Lock the screen.";}; + }; + "Mod+W" = { + action = spawn "noctalia-shell" "ipc" "call" "wallpaper" "toggle"; + hotkey-overlay = {title = "Toggle the wallpaper chooser.";}; + }; + "Mod+Escape" = { + action = spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; + hotkey-overlay = {title = "Toggle the session menu.";}; + }; + + # Screenshots + "Mod+S" = { + action.screenshot-window = {write-to-disk = true;}; + hotkey-overlay = {title = "Take a screenshot of the current window.";}; + }; + "Mod+Shift+S" = { + action.screenshot = {show-pointer = true;}; + hotkey-overlay = {title = "Take a screenshot of a region.";}; + }; + + # Audio + "XF86AudioRaiseVolume" = { + action = spawn "wpctl" "set-volume" "-l" "1.5" "@DEFAULT_AUDIO_SINK@" "5%+"; + hotkey-overlay = {hidden = true;}; + }; + "XF86AudioLowerVolume" = { + action = spawn "wpctl" "set-volume" "-l" "1.5" "@DEFAULT_AUDIO_SINK@" "5%-"; + hotkey-overlay = {hidden = true;}; + }; + "XF86AudioPlay" = { + action = spawn "playerctl" "play-pause"; + hotkey-overlay = {hidden = true;}; + }; + "XF86AudioPrev" = { + action = spawn "playerctl" "previous"; + hotkey-overlay = {hidden = true;}; + }; + "XF86AudioNext" = { + action = spawn "playerctl" "next"; + hotkey-overlay = {hidden = true;}; + }; + + # Niri + "Mod+Shift+Slash" = { + action = show-hotkey-overlay; + hotkey-overlay = {hidden = true;}; + }; + + # Niri windows + "Mod+Q" = { + action = close-window; + hotkey-overlay = {title = "Close the current window.";}; + }; + "Mod+F" = { + action = fullscreen-window; + hotkey-overlay = {title = "Toggle between fullscreen and tiled window.";}; + }; + "Mod+Equal" = { + action = set-column-width "+10%"; + hotkey-overlay = {title = "Increase column width";}; + }; + "Mod+Minus" = { + action = set-column-width "-10%"; + hotkey-overlay = {title = "Decrease column width";}; + }; + "Mod+Shift+M" = { + action = set-column-width "50%"; + hotkey-overlay = {title = "Set column width to 50%";}; + }; + "Mod+M" = { + action = maximize-column; + hotkey-overlay = {title = "Maximize column.";}; + }; + "Mod+V" = { + action = toggle-window-floating; + hotkey-overlay = {title = "Toggle between floating and tiled window.";}; + }; + "Mod+O" = { + action = toggle-overview; + hotkey-overlay = {title = "Toggle overlay.";}; + }; + "Mod+H" = { + action = focus-column-or-monitor-left; + hotkey-overlay = {title = "Focus column on the left. Equivalent bindings for other directions.";}; + }; + "Mod+J" = { + action = focus-window-or-workspace-down; + hotkey-overlay = {hidden = true;}; + }; + "Mod+K" = { + action = focus-window-or-workspace-up; + hotkey-overlay = {hidden = true;}; + }; + "Mod+L" = { + action = focus-column-or-monitor-right; + hotkey-overlay = {hidden = true;}; + }; + "Mod+WheelScrollUp" = { + action = focus-column-left; + hotkey-overlay = {title = "Focus column on the left. Equivalent binding for other direction.";}; + }; + "Mod+WheelScrollDown" = { + action = focus-column-right; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+WheelScrollUp" = { + action = focus-workspace-up; + hotkey-overlay = {title = "Focus previous workspace. Equivalent binding for other direction.";}; + }; + "Mod+Shift+WheelScrollDown" = { + action = focus-workspace-down; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+H" = { + action = move-column-left; + hotkey-overlay = {title = "Move column to the left. Equivalent bindings for other directions.";}; + }; + "Mod+Shift+J" = { + action = move-window-down; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+K" = { + action = move-window-up; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+L" = { + action = move-column-right; + hotkey-overlay = {hidden = true;}; + }; + + # Niri workspaces + "Mod+1" = { + action = focus-workspace 1; + hotkey-overlay = {title = "Focus workspace 1. Equivalent bindings for other workspaces.";}; + }; + "Mod+2" = { + action = focus-workspace 2; + hotkey-overlay = {hidden = true;}; + }; + "Mod+3" = { + action = focus-workspace 3; + hotkey-overlay = {hidden = true;}; + }; + "Mod+4" = { + action = focus-workspace 4; + hotkey-overlay = {hidden = true;}; + }; + "Mod+5" = { + action = focus-workspace 5; + hotkey-overlay = {hidden = true;}; + }; + "Mod+6" = { + action = focus-workspace 6; + hotkey-overlay = {hidden = true;}; + }; + "Mod+7" = { + action = focus-workspace 7; + hotkey-overlay = {hidden = true;}; + }; + "Mod+8" = { + action = focus-workspace 8; + hotkey-overlay = {hidden = true;}; + }; + "Mod+9" = { + action = focus-workspace 9; + hotkey-overlay = {hidden = true;}; + }; + "Mod+0" = { + action = focus-workspace 10; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+1" = { + action.move-window-to-workspace = 1; + hotkey-overlay = {title = "Move current window to workspace 1. Equivalent bindings for other workspaces.";}; + }; + "Mod+Shift+2" = { + action.move-window-to-workspace = 2; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+3" = { + action.move-window-to-workspace = 3; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+4" = { + action.move-window-to-workspace = 4; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+5" = { + action.move-window-to-workspace = 5; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+6" = { + action.move-window-to-workspace = 6; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+7" = { + action.move-window-to-workspace = 7; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+8" = { + action.move-window-to-workspace = 8; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+9" = { + action.move-window-to-workspace = 9; + hotkey-overlay = {hidden = true;}; + }; + "Mod+Shift+0" = { + action.move-window-to-workspace = 10; + hotkey-overlay = {hidden = true;}; + }; + }; + }; + }; + }; + }; +} diff --git a/home/modules/niri/noctalia.nix b/home/modules/niri/noctalia.nix new file mode 100644 index 00000000..00aa22ff --- /dev/null +++ b/home/modules/niri/noctalia.nix @@ -0,0 +1,242 @@ +{color}: { + enable = true; + settings = { + # configure noctalia here; defaults will + # be deep merged with these attributes. + + colorSchemes.predefinedScheme = "Catppuccin"; + + general = { + avatarImage = ../../../config/face.jpeg; + radiusRatio = 0.2; + showScreenCorners = false; + forceBlackScreenCorners = false; + dimDesktop = true; + scaleRatio = 1; + screenRadiusRatio = 1; + animationSpeed = 1; + animationDisabled = false; + compactLockScreen = false; + lockOnSuspend = true; + enableShadows = true; + shadowDirection = "bottom_right"; + shadowOffsetX = 2; + shadowOffsetY = 3; + language = ""; + }; + + ui = { + fontDefault = color.font; + fontFixed = color.font; + tooltipsEnabled = true; + panelsAttachedToBar = true; + settingsPanelAttachTobar = true; + fontDefaultScale = 1; + fontFixedScale = 1; + settingsPanelAttachToBar = false; + }; + + location = { + name = "Dortmund, Germany"; + monthBeforeDay = true; + weatherEnabled = true; + useFahrenheit = false; + use12hourFormat = false; + showWeekNumberInCalendar = false; + showCalendarEvents = true; + showCalendarWeather = true; + analogClockInCalendar = false; + firstDayOfWeek = -1; + }; + + screenRecorder = { + directory = "~/Videos/Recordings"; + frameRate = 60; + audioCodec = "aac"; + videoCodec = "h265"; + quality = "very_high"; + colorRange = "limited"; + showCursor = true; + audioSource = "default_output"; + videoSource = "portal"; + }; + + wallpaper = { + enabled = true; + overviewEnabled = true; + directory = "~/NixFlake/wallpapers"; + enableMultiMonitorDirectories = false; + recursiveSearch = false; + setWallpaperOnAllMonitors = true; + defaultWallpaper = ../../../wallpapers/Windows.jpg; + fillMode = "crop"; + fillColor = "#000000"; + randomEnabled = false; + randomIntervalSec = 300; + transitionDuration = 1500; + transitionType = "random"; + transitionEdgeSmoothness = 0.05; + monitors = []; + panelPosition = "follow_bar"; + }; + + appLauncher = { + enableClipboardHistory = true; + position = "center"; + backgroundOpacity = 1; + pinnedExecs = []; + useApp2Unit = false; + sortByMostUsed = true; + terminalCommand = "kitty -e"; + customLaunchPrefixEnabled = false; + customLaunchPrefix = ""; + }; + + dock = { + enabled = false; + }; + + network = { + wifiEnabled = true; + bluetoothEnabled = true; + }; + + notifications = { + enabled = true; + monitors = []; + location = "top_right"; + overlayLayer = true; + backgroundOpacity = 1; + respectExpireTimeout = false; + lowUrgencyDuration = 3; + normalUrgencyDuration = 8; + criticalUrgencyDuration = 15; + }; + + osd = { + enabled = true; + location = "top_right"; + monitors = []; + autoHideMs = 2000; + overlayLayer = true; + }; + + audio = { + volumeStep = 5; + volumeOverdrive = true; + cavaFrameRate = 30; + visualizerType = "linear"; + visualizerQuality = "high"; + mprisBlacklist = []; + preferredPlayer = ""; + }; + + nightLight = { + enabled = false; + forced = false; + autoSchedule = true; + nightTemp = "5000"; + dayTemp = "6500"; + manualSunrise = "06:30"; + manualSunset = "21:30"; + }; + + sessionMenu = { + countdownDuration = 10000; + enableCountdown = true; + position = "center"; + powerOptions = [ + { + action = "lock"; + enabled = true; + } + { + action = "suspend"; + enabled = false; + } + { + action = "reboot"; + enabled = true; + } + { + action = "logout"; + enabled = true; + } + { + action = "shutdown"; + enabled = true; + } + ]; + showHeader = true; + }; + + bar = { + density = "default"; + position = "top"; + showCapsule = false; + outerCorners = false; + exclusive = true; + backgroundOpacity = 1; + monitors = []; + floating = false; + marginVertical = 0.25; + marginHorizontal = 0.25; + + widgets = { + left = [ + { + id = "SidePanelToggle"; + useDistroLogo = true; + } + { + hideUnoccupied = false; + id = "Workspace"; + labelMode = "none"; + } + { + id = "ActiveWindow"; + width = 250; # TODO: Doesn't work + } + ]; + center = [ + { + id = "MediaMini"; + width = 250; # TODO: Doesn't work + } + { + id = "AudioVisualizer"; + width = 100; # TODO: Doesn't work + } + ]; + right = [ + { + id = "Volume"; + } + { + id = "Microphone"; + } + { + id = "WiFi"; + } + { + id = "Bluetooth"; + } + { + id = "Tray"; + drawer = false; # TODO: Doesn't work + } + { + formatHorizontal = "yyyy:MM:dd HH:mm"; + formatVertical = "HH mm"; + id = "Clock"; + useMonospacedFont = true; + usePrimaryColor = true; + } + { + id = "NotificationHistory"; + } + ]; + }; + }; + }; +} diff --git a/home/modules/niri/options.nix b/home/modules/niri/options.nix new file mode 100644 index 00000000..852c38c0 --- /dev/null +++ b/home/modules/niri/options.nix @@ -0,0 +1,7 @@ +{ + lib, + mylib, + ... +}: { + enable = lib.mkEnableOption "Niri"; +} diff --git a/system/default.nix b/system/default.nix index f15a9d37..65d2683d 100644 --- a/system/default.nix +++ b/system/default.nix @@ -357,6 +357,10 @@ with mylib.networking; { flake = "/home/${username}/NixFlake"; }; + niri = { + enable = !headless; + }; + ssh.startAgent = true; # Use gnupg starship.enable = true; xwayland.enable = !headless;