From 8452ef7ea69c3cb3bd2b214dca51829f37776534 Mon Sep 17 00:00:00 2001 From: jeirmeister Date: Sat, 2 Nov 2024 02:41:32 -0700 Subject: [PATCH] incorporated elements from novas config and switched to flake -- WARNING, not tested or built yet --- .repo-to-text-settings.yaml | 2 - README.md | 159 + documentation/recovery/README.md | 38 - documentation/support/scripts/README.md | 19 - .../support/scripts/network-recovery.sh | 146 - .../support/troubleshooting/common-issues.md | 51 - .../support/troubleshooting/jovian-nixos.md | 29 - flake.nix | 59 +- .../languages => hosts/common}/default.nix | 0 .../bitwarden.age => hosts/default.nix | 0 hosts/steamnix/default.nix | 77 + lib/conds.nix | 7 + lib/default.nix | 51 + lib/mkHome.nix | 34 + lib/mkHost.nix | 50 + lib/secrets.nix | 15 + lib/utils.nix | 37 + .../core/_security}/default.nix | 3 +- .../core/_security}/gpg.nix | 32 +- modules/core/_security/hardening.nix | 53 + modules/core/_security/ssh.nix | 38 + modules/core/age.nix | 66 + modules/core/default.nix | 26 + modules/core/desktop.nix | 144 + modules/core/filesystem.nix | 24 + modules/core/home-manager.nix | 108 + modules/core/ld.nix | 194 + modules/core/networking.nix | 18 + modules/core/nix.nix | 83 + modules/core/security.nix | 42 + modules/core/user.nix | 59 + modules/core/xdg.nix | 16 + .../home/_editors/_default.nix | 0 .../home/_editors/_sublime.nix | 0 .../home/_editors/_vscode/_default.nix | 0 .../home/_editors/_vscode/_extensions.nix | 0 .../home/_editors/_vscode/_settings.nix | 0 modules/home/comms/discord.nix | 25 + .../home/comms/messengers.nix | 4 - modules/home/defaults.nix | 47 + .../home/development/_default.nix | 0 .../home/development/_env/_default.nix | 0 .../home/development/_env/_paths.nix | 0 .../home/development/_env/_versions.nix | 0 .../home/development/_languages/_default.nix | 0 .../home/development/_languages/_go.nix | 0 .../development/_languages/_javascript.nix | 0 .../_languages/_python/_default.nix | 0 .../_python/_packages/_repo-to-text.nix | 0 .../home/development/_languages/_rust.nix | 0 .../home/development/_tools/_default.nix | 0 .../home/development/_tools/_direnv.nix | 0 .../home/development/_tools/_git.nix | 0 modules/home/development/c.nix | 15 + modules/home/development/java.nix | 19 + modules/home/development/latex.nix | 12 + modules/home/development/lua.nix | 14 + modules/home/development/markdown.nix | 14 + modules/home/development/nix.nix | 27 + modules/home/development/python.nix | 31 + modules/home/development/rust.nix | 9 + modules/home/development/web.nix | 16 + modules/home/firefox/default.nix | 7 + modules/home/firefox/extensions.nix | 13 + modules/home/firefox/firefox.nix | 62 + modules/home/firefox/floorp.nix | 40 + modules/home/firefox/searchEngines.nix | 71 + modules/home/media/gaming.nix | 454 + modules/home/media/obs-studio.nix | 16 + modules/home/terminal/kitty.nix | 136 + modules/home/terminal/konsole.nix | 23 + modules/home/theme/common.nix | 115 + modules/home/theme/konsole.mustache | 64 + modules/home/theme/stylix.nix | 165 + .../home/virtualization/virtualization.nix | 36 + modules/home/virtualization/waydroid.nix | 10 + .../tailscale.age => profiles/default.nix | 0 profiles/home/default.nix | 22 + profiles/home/desktop.nix | 22 + profiles/home/development.nix | 23 + profiles/home/gaming.nix | 17 + profiles/home/minimal.nix | 11 + profiles/minimal.nix | 9 + profiles/server.nix | 18 + profiles/workstation.nix | 18 + programs/core/security/ssh.nix | 67 - programs/core/shell/zsh.nix | 33 - programs/desktop/default.nix | 9 - programs/gaming/default.nix | 7 - programs/gaming/vr/default.nix | 45 - programs/terminal/default.nix | 7 - programs/terminal/kitty.nix | 61 - programs/terminal/tmux/default.nix | 135 - programs/terminal/tmux/tmux-man.md | 56 - proposal.md | 38 - repo_overview.txt | 7519 +++++++++++++++++ secrets/default.nix | 34 + secrets/keys/gpg/private.key | Bin 4971 -> 0 bytes secrets/keys/ssh/id_ed25519 | Bin 433 -> 0 bytes secrets/secrets.nix | 32 +- secrets/users/default.nix | 7 + secrets/users/jeirmeister.nix | 31 + .../users/jeirmeister/_keys/_gpg/_private.key | Bin 0 -> 4949 bytes .../jeirmeister/_keys/_gpg/_public.key} | Bin .../users/jeirmeister/_keys/_ssh/_id_ed25519 | 7 + .../jeirmeister/_keys/_ssh/_id_ed25519.pub} | 0 secrets/users/jeirmeister/default.nix | 38 + .../jeirmeister/passwords/_bitwarden.age | 0 secrets/users/jeirmeister/passwords/_sudo.age | 0 .../jeirmeister/passwords/_tailscale.age | 0 system/boot/default.nix | 8 + system/boot/quietboot.nix | 16 + system/boot/systemd-boot.nix | 12 + system/default.nix | 9 + .../desktop/_plasma6.nix | 0 system/desktop/appimage.nix | 19 + system/desktop/default.nix | 8 + system/desktop/plasma6.nix | 90 + system/hardware/bluetooth.nix | 14 + system/hardware/hardware-acceleration.nix | 25 + system/hardware/qmk.nix | 11 + system/hardware/rgb.nix | 10 + system/locales/us-english.nix | 26 + system/services/flatpak.nix | 32 + system/services/printing.nix | 27 + system/services/sunshine.nix | 18 + system/services/syncthing.nix | 19 + system/services/tailscale.nix | 16 + {programs/core => system}/shell/aliases.nix | 0 system/shell/atuin.nix | 37 + {programs/core => system}/shell/bash.nix | 0 system/shell/bat.nix | 24 + system/shell/cava.nix | 43 + {programs/core => system}/shell/default.nix | 0 system/shell/pass.nix | 14 + system/shell/shell-utils.nix | 68 + system/shell/tmux.nix | 174 + system/shell/zsh.nix | 140 + users/jeirmeister/config/git.nix | 10 + users/jeirmeister/config/kde6/common.nix | 63 + users/jeirmeister/config/kde6/panels.nix | 109 + users/jeirmeister/config/pass.nix | 3 + users/jeirmeister/config/ssh.nix | 23 + users/jeirmeister/config/theme.nix | 50 + users/jeirmeister/config/virt-manager.nix | 28 + users/jeirmeister/config/vr.nix | 21 + users/jeirmeister/config/zsh.nix | 60 + .../dotfiles/alvr/active_runtime.json | 8 + users/jeirmeister/dotfiles/alvr/session.json | 1139 +++ users/jeirmeister/dotfiles/kitty/default.conf | 10 + .../dotfiles/openrgb/rgb-default-effect.json | 95 + .../dotfiles/openrgb/rgb-effect-settings.json | 27 + users/jeirmeister/dotfiles/tmuxp/session.yaml | 13 + users/jeirmeister/monsterbabe.nix | 24 + users/jeirmeister/steamdeck.nix | 13 + users/jeirmeister/system.nix | 168 + 156 files changed, 13302 insertions(+), 813 deletions(-) create mode 100644 README.md delete mode 100644 documentation/recovery/README.md delete mode 100644 documentation/support/scripts/README.md delete mode 100755 documentation/support/scripts/network-recovery.sh delete mode 100644 documentation/support/troubleshooting/common-issues.md delete mode 100644 documentation/support/troubleshooting/jovian-nixos.md rename {programs/development/languages => hosts/common}/default.nix (100%) rename secrets/passwords/bitwarden.age => hosts/default.nix (100%) create mode 100644 hosts/steamnix/default.nix create mode 100644 lib/conds.nix create mode 100644 lib/default.nix create mode 100644 lib/mkHome.nix create mode 100644 lib/mkHost.nix create mode 100644 lib/secrets.nix create mode 100644 lib/utils.nix rename {programs/core/security => modules/core/_security}/default.nix (52%) rename {programs/core/security => modules/core/_security}/gpg.nix (60%) create mode 100644 modules/core/_security/hardening.nix create mode 100644 modules/core/_security/ssh.nix create mode 100644 modules/core/age.nix create mode 100644 modules/core/default.nix create mode 100644 modules/core/desktop.nix create mode 100755 modules/core/filesystem.nix create mode 100644 modules/core/home-manager.nix create mode 100644 modules/core/ld.nix create mode 100644 modules/core/networking.nix create mode 100644 modules/core/nix.nix create mode 100755 modules/core/security.nix create mode 100644 modules/core/user.nix create mode 100644 modules/core/xdg.nix rename programs/desktop/editors/default.nix => modules/home/_editors/_default.nix (100%) rename programs/desktop/editors/sublime.nix => modules/home/_editors/_sublime.nix (100%) rename programs/desktop/editors/vscode/default.nix => modules/home/_editors/_vscode/_default.nix (100%) rename programs/desktop/editors/vscode/extensions.nix => modules/home/_editors/_vscode/_extensions.nix (100%) rename programs/desktop/editors/vscode/settings.nix => modules/home/_editors/_vscode/_settings.nix (100%) create mode 100644 modules/home/comms/discord.nix rename programs/desktop/apps.nix => modules/home/comms/messengers.nix (80%) create mode 100644 modules/home/defaults.nix rename programs/development/default.nix => modules/home/development/_default.nix (100%) rename programs/development/env/default.nix => modules/home/development/_env/_default.nix (100%) rename programs/development/env/paths.nix => modules/home/development/_env/_paths.nix (100%) rename programs/development/env/versions.nix => modules/home/development/_env/_versions.nix (100%) rename secrets/passwords/sudo.age => modules/home/development/_languages/_default.nix (100%) rename programs/development/languages/go.nix => modules/home/development/_languages/_go.nix (100%) rename programs/development/languages/javascript.nix => modules/home/development/_languages/_javascript.nix (100%) rename programs/development/languages/python/default.nix => modules/home/development/_languages/_python/_default.nix (100%) rename programs/development/languages/python/packages/repo-to-text.nix => modules/home/development/_languages/_python/_packages/_repo-to-text.nix (100%) rename programs/development/languages/rust.nix => modules/home/development/_languages/_rust.nix (100%) rename programs/development/tools/default.nix => modules/home/development/_tools/_default.nix (100%) rename programs/development/tools/direnv.nix => modules/home/development/_tools/_direnv.nix (100%) rename programs/development/tools/git.nix => modules/home/development/_tools/_git.nix (100%) create mode 100644 modules/home/development/c.nix create mode 100644 modules/home/development/java.nix create mode 100644 modules/home/development/latex.nix create mode 100644 modules/home/development/lua.nix create mode 100644 modules/home/development/markdown.nix create mode 100644 modules/home/development/nix.nix create mode 100644 modules/home/development/python.nix create mode 100644 modules/home/development/rust.nix create mode 100644 modules/home/development/web.nix create mode 100644 modules/home/firefox/default.nix create mode 100644 modules/home/firefox/extensions.nix create mode 100644 modules/home/firefox/firefox.nix create mode 100644 modules/home/firefox/floorp.nix create mode 100644 modules/home/firefox/searchEngines.nix create mode 100644 modules/home/media/gaming.nix create mode 100644 modules/home/media/obs-studio.nix create mode 100644 modules/home/terminal/kitty.nix create mode 100644 modules/home/terminal/konsole.nix create mode 100644 modules/home/theme/common.nix create mode 100644 modules/home/theme/konsole.mustache create mode 100644 modules/home/theme/stylix.nix create mode 100755 modules/home/virtualization/virtualization.nix create mode 100644 modules/home/virtualization/waydroid.nix rename secrets/passwords/tailscale.age => profiles/default.nix (100%) create mode 100644 profiles/home/default.nix create mode 100644 profiles/home/desktop.nix create mode 100644 profiles/home/development.nix create mode 100644 profiles/home/gaming.nix create mode 100644 profiles/home/minimal.nix create mode 100644 profiles/minimal.nix create mode 100644 profiles/server.nix create mode 100644 profiles/workstation.nix delete mode 100644 programs/core/security/ssh.nix delete mode 100644 programs/core/shell/zsh.nix delete mode 100644 programs/desktop/default.nix delete mode 100644 programs/gaming/default.nix delete mode 100644 programs/gaming/vr/default.nix delete mode 100644 programs/terminal/default.nix delete mode 100644 programs/terminal/kitty.nix delete mode 100644 programs/terminal/tmux/default.nix delete mode 100644 programs/terminal/tmux/tmux-man.md delete mode 100644 proposal.md create mode 100644 repo_overview.txt delete mode 100644 secrets/keys/gpg/private.key delete mode 100644 secrets/keys/ssh/id_ed25519 create mode 100644 secrets/users/default.nix create mode 100644 secrets/users/jeirmeister.nix create mode 100644 secrets/users/jeirmeister/_keys/_gpg/_private.key rename secrets/{keys/gpg/public.key => users/jeirmeister/_keys/_gpg/_public.key} (100%) create mode 100644 secrets/users/jeirmeister/_keys/_ssh/_id_ed25519 rename secrets/{keys/ssh/id_ed25519.pub => users/jeirmeister/_keys/_ssh/_id_ed25519.pub} (100%) create mode 100644 secrets/users/jeirmeister/default.nix create mode 100644 secrets/users/jeirmeister/passwords/_bitwarden.age create mode 100644 secrets/users/jeirmeister/passwords/_sudo.age create mode 100644 secrets/users/jeirmeister/passwords/_tailscale.age create mode 100644 system/boot/default.nix create mode 100755 system/boot/quietboot.nix create mode 100644 system/boot/systemd-boot.nix create mode 100644 system/default.nix rename programs/desktop/plasma/default.nix => system/desktop/_plasma6.nix (100%) create mode 100644 system/desktop/appimage.nix create mode 100644 system/desktop/default.nix create mode 100644 system/desktop/plasma6.nix create mode 100644 system/hardware/bluetooth.nix create mode 100644 system/hardware/hardware-acceleration.nix create mode 100644 system/hardware/qmk.nix create mode 100755 system/hardware/rgb.nix create mode 100644 system/locales/us-english.nix create mode 100755 system/services/flatpak.nix create mode 100644 system/services/printing.nix create mode 100644 system/services/sunshine.nix create mode 100644 system/services/syncthing.nix create mode 100755 system/services/tailscale.nix rename {programs/core => system}/shell/aliases.nix (100%) create mode 100644 system/shell/atuin.nix rename {programs/core => system}/shell/bash.nix (100%) create mode 100755 system/shell/bat.nix create mode 100644 system/shell/cava.nix rename {programs/core => system}/shell/default.nix (100%) create mode 100644 system/shell/pass.nix create mode 100644 system/shell/shell-utils.nix create mode 100644 system/shell/tmux.nix create mode 100644 system/shell/zsh.nix create mode 100644 users/jeirmeister/config/git.nix create mode 100644 users/jeirmeister/config/kde6/common.nix create mode 100644 users/jeirmeister/config/kde6/panels.nix create mode 100644 users/jeirmeister/config/pass.nix create mode 100644 users/jeirmeister/config/ssh.nix create mode 100644 users/jeirmeister/config/theme.nix create mode 100644 users/jeirmeister/config/virt-manager.nix create mode 100644 users/jeirmeister/config/vr.nix create mode 100644 users/jeirmeister/config/zsh.nix create mode 100644 users/jeirmeister/dotfiles/alvr/active_runtime.json create mode 100644 users/jeirmeister/dotfiles/alvr/session.json create mode 100644 users/jeirmeister/dotfiles/kitty/default.conf create mode 100644 users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json create mode 100644 users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json create mode 100644 users/jeirmeister/dotfiles/tmuxp/session.yaml create mode 100644 users/jeirmeister/monsterbabe.nix create mode 100644 users/jeirmeister/steamdeck.nix create mode 100644 users/jeirmeister/system.nix diff --git a/.repo-to-text-settings.yaml b/.repo-to-text-settings.yaml index a242bdd..ec769d9 100644 --- a/.repo-to-text-settings.yaml +++ b/.repo-to-text-settings.yaml @@ -9,8 +9,6 @@ gitignore-import-and-ignore: True # and "Contents of ..." sections ignore-tree-and-content: - ".repo-to-text-settings.yaml" - - "documentation" - - ".git-crypt" # Ignore files and directories for "Contents of ..." section ignore-content: diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae6e4ce --- /dev/null +++ b/README.md @@ -0,0 +1,159 @@ +# NixOS Configuration Structure + +This repository contains a NixOS configuration managed through a flake-driven approach. Each directory serves a specific purpose in the overall configuration structure. + +## Directory Structure Overview + +### `flake.nix` +The entry point and source of truth for the entire configuration. This file: +- Defines system configurations +- Sets up home-manager configurations +- Enables profiles +- Manages input sources +- Configures the Nix environment + +### `lib/` +Library functions and utilities that power the configuration system. + +- `conds.nix`: Condition checking helpers for configuration logic +- `default.nix`: Main library entry point that re-exports all functions +- `mkHome.nix`: Home-manager configuration builder +- `mkHost.nix`: NixOS host configuration builder +- `secrets.nix`: Secret management helper functions +- `utils.nix`: General utility functions used throughout the configuration + +### `profiles/` +Profile definitions that enable specific sets of modules and configurations. + +- `core/`: System-level profiles + - `minimal.nix`: Basic system setup + - `workstation.nix`: Desktop/laptop configuration + - `server.nix`: Server-specific setup + +- `home/`: Home-manager profiles + - `desktop.nix`: Desktop environment configuration + - `development.nix`: Development tools and settings + - `gaming.nix`: Gaming-related configuration + +Profiles are enabled through the flake.nix and determine which modules are activated. + +### `modules/` +Module definitions that implement actual functionality. Modules are enabled by profiles. + +- `core/`: System-level modules + - `age.nix`: Age encryption setup + - `desktop.nix`: Desktop environment fundamentals + - `filesystem.nix`: Filesystem configurations + - `home-manager.nix`: Home-manager integration + - `networking.nix`: Network configuration + - `nix.nix`: Nix package manager settings + - `security/`: Security-related modules + - `user.nix`: User management + - `xdg.nix`: XDG base directory support + +- `home/`: Home-manager modules + - `comms/`: Communication tools + - `development/`: Development environments + - `firefox/`: Browser configuration + - `media/`: Media applications + - `terminal/`: Terminal emulators + - `theme/`: Theming configuration + - `virtualization/`: Virtualization tools + +### `system/` +System-level configurations that are used by modules. + +- `boot/`: Boot-related configurations + - `quietboot.nix`: Silent boot configuration + - `systemd-boot.nix`: Systemd-boot setup + +- `desktop/`: Desktop environment configurations + - `appimage.nix`: AppImage support + - `plasma6.nix`: KDE Plasma 6 configuration + +- `hardware/`: Hardware-specific settings + - `bluetooth.nix`: Bluetooth configuration + - `hardware-acceleration.nix`: GPU acceleration + - `qmk.nix`: QMK keyboard firmware + - `rgb.nix`: RGB lighting control + +- `locales/`: Language and locale settings + - `us-english.nix`: US English locale configuration + +- `services/`: System services + - `flatpak.nix`: Flatpak support + - `printing.nix`: Printer configuration + - `sunshine.nix`: Sunshine streaming + - `syncthing.nix`: Syncthing file sync + - `tailscale.nix`: Tailscale VPN + +- `shell/`: Shell configurations + - `aliases.nix`: Shell aliases + - `atuin.nix`: Shell history database + - `zsh.nix`: Zsh configuration + - `tmux.nix`: Tmux terminal multiplexer + +### `secrets/` +Secret management using age encryption. + +- `encrypted/`: Encrypted secret files +- `identities/`: Age identities for decryption +- `users/`: User-specific secret configurations + - `${username}/`: Per-user secret definitions + +### `hosts/` +Host-specific configurations created via mkHost. + +- `${hostname}/` + - `hardware-configuration.nix`: Hardware-specific settings + - `default.nix`: Host-specific overrides + +### `users/` +User-specific configurations created via mkHome. + +- `${username}/` + - `config/`: User-specific configurations + - `dotfiles/`: User dotfiles + - `${hostname}.nix`: Host-specific user settings + +### `pkgs/` +Custom package definitions and overlays. + +- `default.nix`: Entry point for custom packages +- `overlays/`: Nixpkgs overlays + - `default.nix`: Main overlay entry point + - `modifications/`: Modified existing packages + - `custom/`: Custom package definitions + - `patches/`: Package patches for existing packages + +The pkgs directory serves several purposes: +- Define custom packages not available in nixpkgs +- Modify existing packages from nixpkgs +- Create overlays for system-wide package modifications +- Store patches for package modifications + +Package definitions here can be used throughout the configuration by: +1. Being imported through overlays in flake.nix +2. Direct reference in module configurations +3. Usage in home-manager configurations +4. Integration with development environments + +## Configuration Flow + +1. `flake.nix` initiates configuration +2. `lib` functions build configurations +3. Profiles enable appropriate modules +4. Modules implement functionality using system configurations +5. Secrets are applied where needed +6. Host-specific configurations override as needed +7. User configurations are applied through home-manager + +## Important Notes + +- Configurations should flow from the flake.nix +- Profiles should enable modules, not implement functionality +- Modules should be composable and configurable +- System configurations should be reusable +- Secrets should be managed through age/agenix +- Host configurations should only contain necessary overrides +- User configurations should be host-aware \ No newline at end of file diff --git a/documentation/recovery/README.md b/documentation/recovery/README.md deleted file mode 100644 index a91cf70..0000000 --- a/documentation/recovery/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# NixOS Steam Deck Recovery Procedures - -This documentation covers recovery procedures for NixOS on Steam Deck. It was created based on real recovery scenarios and provides practical solutions for common issues. - -## Quick Reference - -1. Boot Issues - - [Boot Recovery Guide](./boot-recovery.md) - - Common root causes: filesystem mounts, hardware configuration - -2. Network Issues - - [Network Recovery Guide](./network-recovery.md) - - Essential for rebuilding with Jovian packages - -3. Filesystem Issues - - [Filesystem Troubleshooting](./filesystem-issues.md) - - Handling mount points and permissions - -## Emergency Recovery Steps - -1. Boot into emergency mode -2. Establish network connectivity -3. Fix configuration issues -4. Rebuild system -5. Verify and reboot - -## Prevention Strategies - -1. Maintain separate configurations: - - Main configuration - - Minimal fallback configuration - - Hardware-specific configuration - -2. Regular backups of working configurations - -3. Testing changes in VM before applying - -4. Maintaining recovery tools and scripts \ No newline at end of file diff --git a/documentation/support/scripts/README.md b/documentation/support/scripts/README.md deleted file mode 100644 index c2fb956..0000000 --- a/documentation/support/scripts/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Recovery Scripts - -This directory contains scripts for automating common recovery tasks. - -## Available Scripts - -1. `network-recovery.sh` - - Automates network setup in emergency environment - - Handles both ethernet and wifi configurations - - Usage: `sudo ./network-recovery.sh` - -## Script Development Guidelines - -1. All scripts should: - - Include clear documentation - - Handle errors gracefully - - Provide status feedback - - Support both automatic and interactive modes - - Create backups before making changes \ No newline at end of file diff --git a/documentation/support/scripts/network-recovery.sh b/documentation/support/scripts/network-recovery.sh deleted file mode 100755 index 4e43dd0..0000000 --- a/documentation/support/scripts/network-recovery.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Function to print status messages -print_status() { - echo -e "${GREEN}[*]${NC} $1" -} - -print_error() { - echo -e "${RED}[!]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[!]${NC} $1" -} - -# Find ethernet interface -find_interface() { - local interface=$(ip link show | grep enp | cut -d: -f2 | tr -d ' ' | head -n1) - if [ -z "$interface" ]; then - print_error "No ethernet interface found" - exit 1 - } - echo "$interface" -} - -# Prompt for network configuration -get_network_config() { - local default_interface=$(find_interface) - - echo "Current network interfaces:" - ip link show - - read -p "Enter interface name [$default_interface]: " interface - interface=${interface:-$default_interface} - - read -p "Enter static IP address (e.g., 10.0.0.68): " static_ip - read -p "Enter gateway IP address (e.g., 10.0.0.1): " gateway_ip - - # Validate IP addresses - if [[ ! $static_ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - print_error "Invalid static IP format" - exit 1 - } - - if [[ ! $gateway_ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - print_error "Invalid gateway IP format" - exit 1 - } -} - -# Configure network -setup_network() { - print_status "Setting up network interface $interface..." - - # Clear any existing IP addresses - ip addr flush dev $interface - - # Bring up interface - ip link set $interface up - if [ $? -ne 0 ]; then - print_error "Failed to bring up interface" - exit 1 - } - - # Add IP address - ip addr add $static_ip/24 dev $interface - if [ $? -ne 0 ]; then - print_error "Failed to set IP address" - exit 1 - } - - # Remove any existing default routes - ip route del default 2>/dev/null - - # Add default route - ip route add default via $gateway_ip dev $interface - if [ $? -ne 0 ]; then - print_error "Failed to add default route" - exit 1 - } - - # Configure DNS - print_status "Configuring DNS..." - echo "nameserver $gateway_ip" > /etc/resolv.conf - echo "nameserver 8.8.8.8" >> /etc/resolv.conf - echo "nameserver 8.8.4.4" >> /etc/resolv.conf - - # Disable IPv6 - print_status "Disabling IPv6..." - sysctl -w net.ipv6.conf.all.disable_ipv6=1 - sysctl -w net.ipv6.conf.default.disable_ipv6=1 - sysctl -w net.ipv6.conf.lo.disable_ipv6=1 -} - -# Test connectivity -test_connectivity() { - print_status "Testing connectivity..." - - # Test local network - print_status "Pinging gateway..." - if ! ping -c 1 $gateway_ip >/dev/null 2>&1; then - print_error "Cannot ping gateway" - return 1 - } - - # Test DNS resolution - print_status "Testing DNS resolution..." - if ! ping -c 1 github.com >/dev/null 2>&1; then - print_warning "DNS resolution failed" - return 1 - } - - print_status "Network setup complete and functional!" - return 0 -} - -# Main execution -main() { - if [[ $EUID -ne 0 ]]; then - print_error "This script must be run as root" - exit 1 - } - - print_status "NixOS Network Recovery Script" - print_status "===============================" - - get_network_config - setup_network - test_connectivity - - if [ $? -eq 0 ]; then - print_status "You should now be able to run nixos-rebuild" - else - print_error "Network setup completed but connectivity test failed" - print_warning "Check your network settings and try again" - fi -} - -# Run main function -main "$@" diff --git a/documentation/support/troubleshooting/common-issues.md b/documentation/support/troubleshooting/common-issues.md deleted file mode 100644 index 084112c..0000000 --- a/documentation/support/troubleshooting/common-issues.md +++ /dev/null @@ -1,51 +0,0 @@ -# Common Issues and Solutions - -## Network Configuration Issues - -### Symptoms -- Unable to fetch packages -- No internet connectivity in emergency mode - -### Solution -1. Use network-recovery.sh script -2. Manual network configuration: - ```bash - ip link set INTERFACE up - ip addr add IP_ADDRESS/24 dev INTERFACE - ip route add default via GATEWAY - echo "nameserver 8.8.8.8" > /etc/resolv.conf - ``` - -## Filesystem Mount Issues - -### Symptoms -- Read-only filesystem errors -- Unable to modify configuration -- Failed mounts during boot - -### Solution -1. Identify problematic mounts: - ```bash - mount | grep ro - lsblk -f - ``` -2. Remount filesystems: - ```bash - mount -o remount,rw / - mount -o remount,rw /nix/store - ``` -3. Check/modify hardware-configuration.nix - -## DBus Issues - -### Symptoms -- Failed to connect to bus -- Service startup failures - -### Solution -1. Setup minimal DBus environment: - ```bash - mkdir -p /run/dbus - mount -t tmpfs tmpfs /run - dbus-daemon --system --fork - ``` \ No newline at end of file diff --git a/documentation/support/troubleshooting/jovian-nixos.md b/documentation/support/troubleshooting/jovian-nixos.md deleted file mode 100644 index 80c61f4..0000000 --- a/documentation/support/troubleshooting/jovian-nixos.md +++ /dev/null @@ -1,29 +0,0 @@ -# Jovian NixOS Specific Issues - -## Package Fetching Issues - -### Symptoms -- Unable to fetch Jovian packages -- Build failures related to Jovian components - -### Solution -1. Ensure network connectivity -2. Verify Jovian configuration: - ```nix - jovian = { - hardware.has.amd.gpu = true; - devices.steamdeck.enable = true; - }; - ``` -3. Check Jovian cache availability - -## Hardware Detection Issues - -### Symptoms -- Missing Steam Deck specific features -- Hardware not properly recognized - -### Solution -1. Verify hardware configuration -2. Check kernel modules -3. Review Jovian hardware settings \ No newline at end of file diff --git a/flake.nix b/flake.nix index c03e8e1..d78e153 100644 --- a/flake.nix +++ b/flake.nix @@ -4,60 +4,73 @@ nixConfig = { extra-substituters = [ "https://nix-gaming.cachix.org" + "https://nix-community.cachix.org" ]; extra-trusted-public-keys = [ "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; }; inputs = { # Core dependencies nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11"; + home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; + # System dependencies + systems.url = "github:nix-systems/default"; + + # Additional tools + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + # Gaming-specific inputs nix-gaming = { url = "github:fufexan/nix-gaming"; inputs.nixpkgs.follows = "nixpkgs"; }; - - # Additional tools - agenix = { - url = "github:ryantm/agenix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; }; outputs = { self, nixpkgs, home-manager, ... } @ inputs: let lib = nixpkgs.lib.extend (final: prev: import ./lib { inherit inputs self; lib = final; }); - in - { - nixosConfigurations = { - steamnix = lib.mkHost { - hostname = "steamnix"; - username = "jeirmeister"; - system = "x86_64-linux"; - profiles = [ "gaming" "desktop/plasma" ]; - }; - }; - homeConfigurations = { - "jeirmeister@steamnix" = lib.mkHome { - username = "jeirmeister"; - hostname = "steamnix"; + # Helper function to create specialized system configs + mkSystem = hostName: system: username: + lib.mkHost { + inherit system username hostName; + extraModules = [ + # Add your host-specific modules here + ]; + }; + + # Helper function to create home-manager configs + mkHome = username: hostName: + lib.mkHome { + inherit username hostName; profiles = [ "desktop" "development" "gaming" ]; }; + in + { + # NixOS configurations + nixosConfigurations = { + steamnix = mkSystem "steamnix" "x86_64-linux" "jeirmeister"; }; - # Custom packages and overlays - overlays = import ./overlays { inherit self; }; + # Home-manager configurations + homeConfigurations = { + "jeirmeister@steamnix" = mkHome "jeirmeister" "steamnix"; + }; - # Formatter + # Formatter configuration formatter = lib.forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt); }; } diff --git a/programs/development/languages/default.nix b/hosts/common/default.nix similarity index 100% rename from programs/development/languages/default.nix rename to hosts/common/default.nix diff --git a/secrets/passwords/bitwarden.age b/hosts/default.nix similarity index 100% rename from secrets/passwords/bitwarden.age rename to hosts/default.nix diff --git a/hosts/steamnix/default.nix b/hosts/steamnix/default.nix new file mode 100644 index 0000000..1985a39 --- /dev/null +++ b/hosts/steamnix/default.nix @@ -0,0 +1,77 @@ +{ config, lib, pkgs, ... }: + +let + jovianNixosRev = "f6423d86bec22c25a576b23262495c5536b0d069"; + jovianNixos = builtins.fetchTarball { + url = "https://github.com/Jovian-Experiments/Jovian-NixOS/archive/${jovianNixosRev}.tar.gz"; + sha256 = "sha256:1frd1dfqd97idwf1rj29ab0wvyfa2nx2h3bp9hkbmfa1m802avmb"; + }; +in +{ + imports = [ + ../common + ./hardware-configuration.nix + (jovianNixos + "/modules") + ]; + + # Configure host type + hostConfigs = { + hostType = "steamdeck"; + hasGaming = true; + hasVR = true; + }; + + # Steam Deck Specific Configuration + jovian = { + hardware.has.amd.gpu = true; + devices.steamdeck = { + enable = true; + enableControllerUdevRules = true; + enableDefaultStage1Modules = true; + enablePerfControlUdevRules = true; + enableOsFanControl = true; + enableSoundSupport = true; + enableXorgRotation = true; + enableKernelPatches = true; + enableFwupdBiosUpdates = false; + autoUpdate = false; + }; + steam.enable = false; + workarounds.ignoreMissingKernelModules = true; + }; + + # Hardware and Display Configuration + hardware.video = { + displaylink.enable = true; + }; + + services = { + xserver = { + enable = true; + xkb.layout = "us"; + videoDrivers = [ "displaylink" "modesetting" ]; + + desktopManager.plasma6 = { + enable = true; + extraSessionCommands = '' + ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0; + ''; + }; + + displayManager = { + sddm = { + enable = true; + wayland = true; + }; + sessionCommands = '' + ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0 + ''; + }; + }; + + pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; + }; + }; diff --git a/lib/conds.nix b/lib/conds.nix new file mode 100644 index 0000000..93aa8f8 --- /dev/null +++ b/lib/conds.nix @@ -0,0 +1,7 @@ +{ lib }: +{ + defaultStateVersion = "24.05"; + runsDesktop = config: config.modules.desktop.enable; + isWayland = config: config.modules.desktop.wayland.enable; + isX11 = config: config.modules.desktop.x11.enable; +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..5aff1d9 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,51 @@ +{ self, inputs, lib }: +let + # Helper functions for internal use + internals = { + sys = import inputs.systems; + # Add standard lib function sets + inherit (lib) types mkOption; + }; + + # Define pkgsFor before using it + pkgsFor = lib.genAttrs internals.sys (system: import inputs.nixpkgs { + inherit system; + overlays = builtins.attrValues self.overlays; + config.allowUnfree = true; + }); +in +{ + # Re-export all our functions + inherit (import ./mkHost.nix { inherit self inputs lib; }) mkHost; + inherit (import ./mkHome.nix { inherit self inputs lib; }) mkHome; + inherit (import ./utils.nix { inherit lib; }) + mkOpt + mkBoolOpt + enable + disable + enableIf + mkModule; + inherit (import ./conds.nix { inherit lib; }) + defaultStateVersion + runsDesktop + isWayland + isX11; + inherit (import ./secrets.nix { inherit lib; }) + mkSecretFile + mkSecretIdentities; + + # System-wide utilities + inherit pkgsFor; + forEachSystem = fn: lib.genAttrs internals.sys (system: fn pkgsFor.${system}); + + # Add mkModule helper function + utilMods = { + mkModule = config: name: module: + lib.mkIf config.modules.${name}.enable module; + + mkEnabledModule = config: name: module: { + options.modules.${name}.enable = lib.mkEnableOption "Enable ${name} configurations"; + config = lib.mkIf config.modules.${name}.enable module; + }; + }; +} diff --git a/lib/mkHome.nix b/lib/mkHome.nix new file mode 100644 index 0000000..e0de65f --- /dev/null +++ b/lib/mkHome.nix @@ -0,0 +1,34 @@ +{ self, inputs, lib }: +let + inherit (lib) mkOption types; +in { + mkHome = { username, hostname, profiles ? [] }: + let + system = "x86_64-linux"; # You can make this configurable if needed + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + in + inputs.home-manager.lib.homeManagerConfiguration { + inherit pkgs; + + extraSpecialArgs = { + inherit username hostname; + }; + + modules = [ + # Base home-manager configuration + ../users/${username}/home.nix + + # Basic home configuration + { + home = { + inherit username; + homeDirectory = "/home/${username}"; + stateVersion = "24.05"; + }; + } + ] ++ (map (profile: ../profiles/${profile}) profiles); + }; +} diff --git a/lib/mkHost.nix b/lib/mkHost.nix new file mode 100644 index 0000000..6eeecb0 --- /dev/null +++ b/lib/mkHost.nix @@ -0,0 +1,50 @@ +{ self, inputs, lib }: +let + inherit (lib) mkOption types; +in { + mkHost = { hostname, username, system ? "x86_64-linux", profiles ? [] }: + let + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + in + inputs.nixpkgs.lib.nixosSystem { + inherit system; + + specialArgs = { + inherit inputs self hostname username; + }; + + modules = [ + # Include host-specific configuration + ../hosts/${hostname}/configuration.nix + + # Include home-manager as a module + inputs.home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = { + inherit username hostname; + }; + users.${username} = { + imports = [ + ../users/${username}/home.nix + ] ++ (map (profile: ../profiles/${profile}) profiles); + }; + }; + } + + # Basic system configuration + { + networking.hostName = hostname; + system.stateVersion = "24.05"; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + } + ]; + }; +} diff --git a/lib/secrets.nix b/lib/secrets.nix new file mode 100644 index 0000000..0eee01c --- /dev/null +++ b/lib/secrets.nix @@ -0,0 +1,15 @@ +{ lib }: +let + internals.agePath = ../secrets; +in { + mkSecretFile = { user, source, destination ? null, owner ? null, group ? null }: + lib.filterAttrs (n: v: v != null) { + file = lib.path.append (internals.agePath + "/${user}") source; + path = destination; + inherit owner group; + }; + + mkSecretIdentities = identity: + lib.lists.forEach identity (x: + lib.path.append (internals.agePath + "/identities") x); +} diff --git a/lib/utils.nix b/lib/utils.nix new file mode 100644 index 0000000..0fa3fc3 --- /dev/null +++ b/lib/utils.nix @@ -0,0 +1,37 @@ +{ lib }: +let + # Helper functions + mkEnableAttrs = value: elems: builtins.listToAttrs (map + (name: { + inherit name; + value.enable = value; + }) + elems); +in +{ + # Option helpers + mkOpt = type: default: lib.mkOption { inherit type default; }; + mkBoolOpt = default: lib.mkOption { type = lib.types.bool; inherit default; }; + + # Module management + mkModule = config: name: module: + lib.mkIf config.modules.${name}.enable module; + + enable = elems: mkEnableAttrs true elems; + disable = elems: mkEnableAttrs false elems; + enableIf = cond: elems: if cond then (mkEnableAttrs true elems) else (mkEnableAttrs false elems); + + # Import helpers + concatImports = { paths ? [ ], include ? [ ], exclude ? [ ] }: + let + isExcluded = path: builtins.elem path exclude; + validPath = path: lib.pathExists path && !isExcluded path; + in + lib.flatten (map + (path: + if validPath path + then path + else [ ] + ) + (paths ++ include)); +} diff --git a/programs/core/security/default.nix b/modules/core/_security/default.nix similarity index 52% rename from programs/core/security/default.nix rename to modules/core/_security/default.nix index 594ea71..30bc3ee 100644 --- a/programs/core/security/default.nix +++ b/modules/core/_security/default.nix @@ -1,8 +1,9 @@ -{ config, pkgs, ... }: +{ config, lib, pkgs, ... }: { imports = [ ./gpg.nix ./ssh.nix + ./hardening.nix ]; } diff --git a/programs/core/security/gpg.nix b/modules/core/_security/gpg.nix similarity index 60% rename from programs/core/security/gpg.nix rename to modules/core/_security/gpg.nix index 60facd6..990d323 100644 --- a/programs/core/security/gpg.nix +++ b/modules/core/_security/gpg.nix @@ -1,20 +1,9 @@ -{ lib, pkgs, ... }: +{ config, lib, pkgs, ... }: -{ +lib.utilMods.mkModule config "security.gpg" { programs.gpg = { enable = true; settings = { - # Your default key - default-key = "0x33A40DF62D35C4A7"; - - # Key server settings - keyserver = "hkps://keys.openpgp.org"; - keyserver-options = "auto-key-retrieve no-honor-keyserver-url"; - - # Trust model settings - trust-model = "tofu+pgp"; - tofu-default-policy = "auto"; - # Modern cipher preferences personal-cipher-preferences = "AES256 AES192 AES"; personal-digest-preferences = "SHA512 SHA384 SHA256"; @@ -37,18 +26,15 @@ enableSshSupport = true; defaultCacheTtl = 1800; maxCacheTtl = 7200; - pinentryPackage = pkgs.pinentry-qt; extraConfig = '' allow-preset-passphrase allow-loopback-pinentry enable-ssh-support write-env-file - default-cache-ttl-ssh 1800 - max-cache-ttl-ssh 7200 ''; }; - # Fix GPG home directory permissions + # Ensure proper GPG directory permissions on activation home.activation.fixGpgPerms = lib.hm.dag.entryAfter [ "writeBoundary" ] '' if [ -d "$HOME/.gnupg" ]; then chmod 700 "$HOME/.gnupg" @@ -56,16 +42,4 @@ find "$HOME/.gnupg" -type d -exec chmod 700 {} \; fi ''; - - # Make sure we have the right packages - home.packages = with pkgs; [ - gnupg - pinentry-qt - pgpdump # Analyze PGP/GPG keys and packets - - # Future secret management tools - sops # Simple encryption tool - age # Modern encryption tool (required for agenix) - ssh-to-age # Convert SSH keys to age keys - ]; } diff --git a/modules/core/_security/hardening.nix b/modules/core/_security/hardening.nix new file mode 100644 index 0000000..6ff7965 --- /dev/null +++ b/modules/core/_security/hardening.nix @@ -0,0 +1,53 @@ +{ config, lib, ... }: + +lib.utilMods.mkModule config "security.hardening" { + # TCP hardening from your original config + boot.kernelModules = [ "tcp_bbr" ]; + boot.kernel.sysctl = { + # Prevent bogus ICMP errors from filling up logs + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering for IP spoofing mitigation + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Disable IP source routing (we're not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Disable ICMP redirects + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # MITM mitigations + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # SYN flood protection + "net.ipv4.tcp_syncookies" = 1; + # TIME-WAIT assassination protection + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # Enable TCP Fast Open + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; + + # Make /tmp volatile + boot.tmp.cleanOnBoot = true; + + # Basic security settings + security = { + # Prevent replacing the running kernel image + protectKernelImage = true; + # Allow terminal users to execute programs + pam.loginLimits = [{ + domain = "@users"; + item = "nofile"; + type = "soft"; + value = 4096; + }]; + }; +} diff --git a/modules/core/_security/ssh.nix b/modules/core/_security/ssh.nix new file mode 100644 index 0000000..093fe2f --- /dev/null +++ b/modules/core/_security/ssh.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +lib.utilMods.mkModule config "security.ssh" { + services.openssh = { + enable = true; + settings = { + # Security hardening + PasswordAuthentication = false; + PermitRootLogin = "no"; + # Automatically remove stale sockets + StreamLocalBindUnlink = "yes"; + }; + }; + + programs.ssh = { + startAgent = true; + extraConfig = '' + AddKeysToAgent yes + UseKeychain yes + IdentitiesOnly yes + HashKnownHosts yes + ''; + + # For better security + serverAliveInterval = 60; + serverAliveCountMax = 2; + }; + + # Ensure SSH directory exists with correct permissions + home.file.".ssh/.keep".text = ""; + home.activation.sshPermissions = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + chmod 700 ~/.ssh + if [ -f ~/.ssh/id_ed25519 ]; then + chmod 600 ~/.ssh/id_ed25519 + chmod 644 ~/.ssh/id_ed25519.pub + fi + ''; +} diff --git a/modules/core/age.nix b/modules/core/age.nix new file mode 100644 index 0000000..c8ef64c --- /dev/null +++ b/modules/core/age.nix @@ -0,0 +1,66 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: let + cfg = config.variables; + pcscdCfg = pkgs.writeText "reader.conf" ""; + pcscdPkg = pkgs.pcsclite; + pcscdPluginEnv = pkgs.buildEnv { + name = "pcscd-plugins"; + paths = map (p: "${p}/pcsc/drivers") [pkgs.ccid]; + }; +in + {imports = with inputs; [agenix.nixosModules.default];} + // { + options.variables.userIdentityPaths = lib.mkOption { + default = []; + type = lib.types.listOf lib.types.path; + description = "List of secret identity paths for the user"; + }; + + config = lib.mkMerge [ + (lib.mkIf (cfg.userIdentityPaths != []) { + age.identityPaths = lib.mkOptionDefault cfg.userIdentityPaths; + hm.age.identityPaths = lib.mkOptionDefault cfg.userIdentityPaths; + }) + + { + home-manager.sharedModules = with inputs; [ + agenix.homeManagerModules.default + ]; + environment.systemPackages = with pkgs; [agenix age age-plugin-yubikey]; + + age.ageBin = "PATH=$PATH:${lib.makeBinPath [pkgs.age-plugin-yubikey]} ${pkgs.age}/bin/age"; + + services.pcscd.enable = lib.mkForce true; + # TODO: Figure out why this is broken + #systemd.services.pcscd.serviceConfig.ExecStart = mkForce [ + # "${pcscdPkg}/bin/pcscd -f -c ${pcscdCfg}" + #]; + + # HACK: Start pcscd before decrypting secrets + boot.initrd.systemd = { + enable = lib.mkDefault true; + packages = [(lib.getBin pcscdPkg)]; + storePaths = [ + "${pcscdPkg}/bin/pcscd" + "${pcscdCfg}" + "${pcscdPluginEnv}" + ]; + + sockets.pcscd.wantedBy = ["sockets.target"]; + services.pcscd = { + environment.PCSCLITE_HP_DROPDIR = pcscdPluginEnv; + after = ["rollback.service"]; + serviceConfig.ExecStart = [ + "" + "${pcscdPkg}/bin/pcscd -f -c ${pcscdCfg}" + ]; + }; + }; + } + ]; + } diff --git a/modules/core/default.nix b/modules/core/default.nix new file mode 100644 index 0000000..87761de --- /dev/null +++ b/modules/core/default.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +{ + options.modules = { + core = lib.mkOption { + type = lib.types.submodule { + options = { + profile = lib.mkOption { + type = lib.types.enum [ "minimal" "workstation" "server" ]; + default = "minimal"; + description = "The core profile to use for this system"; + }; + }; + }; + }; + }; + + config = { + # Import the selected profile + imports = [ ../profiles/core/${config.modules.core.profile}.nix ]; + + # Common core settings that apply to all profiles + nix.settings.auto-optimise-store = true; + boot.tmp.cleanOnBoot = true; + }; +} diff --git a/modules/core/desktop.nix b/modules/core/desktop.nix new file mode 100644 index 0000000..6227782 --- /dev/null +++ b/modules/core/desktop.nix @@ -0,0 +1,144 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.modules.desktop; + waylandEnv = { + NIXOS_OZONE_WL = "1"; + MOZ_ENABLE_WAYLAND = "1"; + GDK_BACKEND = "wayland,x11"; + SDL_VIDEODRIVER = "x11"; + CLUTTER_BACKEND = "wayland"; + # QT_QPA_PLATFORM = "wayland"; + # LIBSEAT_BACKEND = "logind"; + XDG_SESSION_TYPE = "wayland"; + #WLR_NO_HARDWARE_CURSORS = "1"; + # _JAVA_AWT_WM_NONREPARENTING = "1"; + # GDK_SCALE = "2"; + # ELECTRON_OZONE_PLATFORM_HINT = "wayland"; + }; +in { + options.modules.desktop = { + enable = lib.mkEnableOption "Enable desktop configurations"; + x11.enable = lib.mkEnableOption "Enable X11 integration" // {default = true;}; + wayland.enable = lib.mkEnableOption "Enable wayland integration"; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + # X11 Configs + (lib.mkIf cfg.x11.enable { + # Enable the X11 windowing system. + services.xserver = { + enable = true; + + # Configure keymap in X11 + xkb = { + layout = "us"; + variant = ""; + options = "terminate:ctrl_alt_bksp,caps:ctrl_modifier"; + }; + + # Remove xterm terminal + excludePackages = with pkgs; [xterm]; + }; + + # Install installation + environment.systemPackages = with pkgs; [ + # X11 + xorg.xkbutils + xorg.xkill + xorg.libxcb + ]; + }) + # Wayland Configs + (lib.mkIf cfg.wayland.enable { + environment = { + # NOTE This will break stuff if there is a non-wayland user on the same machine, + # but application launchers need this. + sessionVariables = waylandEnv; + # Install necessary wayland protocol packages + systemPackages = with pkgs; [ + #xorg.xeyes + kdePackages.xwaylandvideobridge + libsForQt5.qt5.qtwayland + qt6.qtwayland + ]; + }; + + hm.home.sessionVariables = waylandEnv; + }) + + # Common + { + modules.fonts.enable = true; + services = { + # Enable touchpad support + libinput.enable = true; + # Enable color management service + colord.enable = true; + # Enable pipewire + pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + }; + pulse.enable = true; + }; + }; + environment.systemPackages = with pkgs; [ + #Notifications + libnotify + + #PDF + poppler + + # Enable guestures for touchpad + libinput-gestures + # Install audio configuration tools (Especially important for VR) + pavucontrol + pulseaudio + ]; + + # Enable the RealtimeKit system service + security.rtkit.enable = true; + + # Disable PulseAudio + hardware.pulseaudio.enable = lib.mkForce false; + + # Enable networking + networking.networkmanager.enable = true; + + # Enable for GTK + programs.dconf.enable = true; + + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + wlr.enable = true; + extraPortals = with pkgs; [xdg-desktop-portal-gtk]; + }; + + hm.xdg = { + /* + portal = { + enable = true; + xdgOpenUsePortal = true; + }; + */ + # Don't generate config at the usual place. + # Allow desktop applications to write their file association + # preferences to this file. + configFile."mimeapps.list".enable = false; + # Home-manager also writes xdg-mime-apps configuration to the + # "deprecated" location. Desktop applications will look in this + # list for associations, if no association was found in the + # previous config file. + dataFile."applications/mimeapps.list".force = true; + mimeApps.enable = true; + }; + } + ]); +} diff --git a/modules/core/filesystem.nix b/modules/core/filesystem.nix new file mode 100755 index 0000000..34cf189 --- /dev/null +++ b/modules/core/filesystem.nix @@ -0,0 +1,24 @@ +{pkgs, ...}: { + services.usbmuxd.enable = true; + + environment.systemPackages = with pkgs; [ + libimobiledevice + ifuse # optional, to mount using 'ifuse' + gvfs + usbmuxd + ]; + + boot.supportedFilesystems = [ + "btrfs" + "ext2" + "ext3" + "ext4" + "exfat" + "f2fs" + "fat8" + "fat16" + "fat32" + "ntfs" + "xfs" + ]; +} diff --git a/modules/core/home-manager.nix b/modules/core/home-manager.nix new file mode 100644 index 0000000..9e100f0 --- /dev/null +++ b/modules/core/home-manager.nix @@ -0,0 +1,108 @@ +{ + config, + lib, + self, + inputs, + stateVersion, + hostname, + username, + ... +}: let + hm-config = config.hm; + activationScript = let + commands = builtins.concatStringsSep "\n" ( + map (file: ''rm -fv "${file}" && echo Deleted "${file}"'') hm-config.nukeFiles + ); + in '' + #!/run/current-system/sw/bin/bash + set -o errexit + set -o nounset + + echo "[home-nuker] Nuking files so Home Manager can get its will" + + ${commands} + ''; +in + { + imports = with inputs; [ + home-manager.nixosModules.home-manager + # Let us use hm as shorthand for home-manager config + (lib.mkAliasOptionModule ["hm"] ["home-manager" "users" username]) + ]; + } + // lib.utilMods.mkEnabledModule config "core.homeManager" { + # Home file nuking script that deletes stuff just before we run home-manager's activation scripts + system.userActivationScripts.home-conflict-file-nuker = lib.mkIf (hm-config.nukeFiles != []) activationScript; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = {inherit self inputs stateVersion hostname username;}; + backupFileExtension = ".bak"; + sharedModules = with inputs; + [ + #agenix.homeManagerModules.default + nix-index-database.hmModules.nix-index + plasma-manager.homeManagerModules.plasma-manager + #stylix.homeManagerModules.stylix + ] + # Import modules specific and user configs for home-manager + # TODO: Maybe make ./config in users be available to NixOS too and just pass any Home-Manager configs via hm? + ++ lib.utils.concatImports { + paths = [ + ../home + ../../users/${username}/config + ]; + }; + + # Import specific stuff for the user + users.${username} = import ../../users/${username}/${config.networking.hostName}.nix; + }; + + hm = { + nix.settings = config.nix.settings; + + programs = { + home-manager.enable = true; + emacs.enable = lib.mkDefault true; + git.enable = lib.mkDefault true; + ssh.enable = lib.mkDefault true; + gpg.enable = lib.mkDefault true; + }; + + home = { + inherit username stateVersion; + inherit (config.variables.user) homeDirectory; + preferXdgDirectories = true; + + sessionVariables = { + FLAKE = "${hm-config.home.homeDirectory}/Documents/NixConfig"; + XDG_BIN_HOME = "${hm-config.home.homeDirectory}/.local/bin"; + + ANDROID_USER_HOME = "${hm-config.xdg.dataHome}/android"; + CUDA_CACHE_PATH = "${hm-config.xdg.cacheHome}/nv"; + TLDR_CACHE_DIR = "${hm-config.xdg.cacheHome}/tldr"; + }; + sessionPath = ["${hm-config.home.sessionVariables.XDG_BIN_HOME}"]; + shellAliases.wget = ''wget --hsts-file="${hm-config.xdg.dataHome}/wget-hsts"''; + }; + + # (De)activate wanted systemd units when changing configs + systemd.user.startServices = "sd-switch"; + + # Enable HTML help page + manual.html.enable = true; + + news.display = "silent"; + + # Make sure XDG is enabled + xdg.enable = true; + + xresources.path = lib.mkForce "${hm-config.xdg.configHome}/.Xresources"; + + gtk = { + enable = true; + gtk2.configLocation = lib.mkForce "${hm-config.xdg.configHome}/gtk-2.0/gtkrc"; + }; + }; + } diff --git a/modules/core/ld.nix b/modules/core/ld.nix new file mode 100644 index 0000000..e8a429a --- /dev/null +++ b/modules/core/ld.nix @@ -0,0 +1,194 @@ +# Taken from https://github.com/ywmaa/dotfiles/blob/main/nix-config/dynamic_binaries_support.nix +{pkgs, ...}: { + # allow running binaries + services.envfs.enable = true; + programs.nix-ld.enable = true; + programs.nix-ld.libraries = with pkgs; [ + # Needed for operating system detection until + # https://github.com/ValveSoftware/steam-for-linux/issues/5909 is resolved + lsb-release + # Errors in output without those + pciutils + # Games' dependencies + xorg.xrandr + which + # Needed by gdialog, including in the steam-runtime + perl + # Open URLs + xdg-utils + iana-etc + # Steam Play / Proton + python3 + + # It tries to execute xdg-user-dir and spams the log with command not founds + xdg-user-dirs + + # electron based launchers need newer versions of these libraries than what runtime provides + sqlite + # Godot + Blender + stdenv.cc.cc + # Blender + libdecor + # Godot Engine + libunwind + # Others + xorg.libXcomposite + xorg.libXtst + xorg.libXrandr + xorg.libXext + xorg.libX11 + xorg.libXfixes + xorg.libxkbfile + libGL + libva + libva-utils + #pipewire.lib + ocamlPackages.alsa + alsa-lib + libpulseaudio + # steamwebhelper + harfbuzz + libthai + pango + brotli + fuse3 + icu + libglvnd + libnotify + libxml2 + openssl + pipewire + pulseaudio + systemd + x264 + libplist + + lsof # friends options won't display "Launch Game" without it + file # called by steam's setup.sh + + # dependencies for mesa drivers, needed inside pressure-vessel + mesa + mesa.llvmPackages.llvm.lib + vulkan-loader + expat + wayland + xorg.libxcb + xorg.libXdamage + xorg.libxshmfence + xorg.libXxf86vm + libelf + (lib.getLib elfutils) + + # Without these it silently fails + xorg.libXinerama + xorg.libXcursor + xorg.libXrender + xorg.libXScrnSaver + xorg.libXi + xorg.libSM + xorg.libICE + gnome2.GConf + curlWithGnuTls + nspr + nss + cups + libcap + SDL2 + libusb1 + dbus + dbus-glib + gsettings-desktop-schemas + ffmpeg + libudev0-shim + + # Verified games requirements + fontconfig + freetype + xorg.libXt + xorg.libXmu + libogg + libvorbis + SDL + SDL2_image + glew110 + libidn + tbb + zlib + + # SteamVR + procps + usbutils + udev + + # Other things from runtime + glib + gtk2 + gtk3 + bzip2 + flac + freeglut + libjpeg + libpng + libpng12 + libsamplerate + libmikmod + libtheora + libtiff + pixman + speex + SDL_image + SDL_ttf + SDL_mixer + SDL2_ttf + SDL2_mixer + libappindicator-gtk2 + libappindicator-gtk3 + libdbusmenu-gtk2 + libindicator-gtk2 + libcaca + libcanberra + libgcrypt + libvpx + librsvg + xorg.libXft + libvdpau + + # required by coreutils stuff to run correctly + # Steam ends up with LD_LIBRARY_PATH=:/usr/lib: + # which overrides DT_RUNPATH in our binaries, so it tries to dynload the + # very old versions of stuff from the runtime. + # FIXME: how do we even fix this correctly + attr + + # Not formally in runtime but needed by some games + at-spi2-atk + at-spi2-core # CrossCode + gst_all_1.gstreamer + gst_all_1.gst-plugins-ugly + gst_all_1.gst-plugins-base + json-glib # paradox launcher (Stellaris) + libdrm + libxkbcommon # paradox launcher + libxcrypt # Alien Isolation, XCOM 2, Company of Heroes 2 + mono + xorg.xkeyboardconfig + xorg.libpciaccess + icu # dotnet runtime, e.g. Stardew Valley + + # screeps dependencies + atk + cairo + gdk-pixbuf + + # Prison Architect + libGLU + libuuid + libbsd + + # Loop Hero + libidn2 + libpsl + nghttp2.lib + rtmpdump + ]; +} diff --git a/modules/core/networking.nix b/modules/core/networking.nix new file mode 100644 index 0000000..2f71a8b --- /dev/null +++ b/modules/core/networking.nix @@ -0,0 +1,18 @@ +_: { + networking.firewall.enable = true; + systemd.network.wait-online.enable = false; + systemd.services.NetworkManager-wait-online.enable = false; + + # Enable mDNS + services.avahi = { + enable = true; + nssmdns4 = true; + # for a WiFi printer + openFirewall = true; + # Make user systemd service work with avahi + publish = { + enable = true; + userServices = true; + }; + }; +} diff --git a/modules/core/nix.nix b/modules/core/nix.nix new file mode 100644 index 0000000..48308a5 --- /dev/null +++ b/modules/core/nix.nix @@ -0,0 +1,83 @@ +{ + config, + pkgs, + self, + lib, + inputs, + ... +}: { + # Config Nixpkgs + nixpkgs = { + overlays = builtins.attrValues self.overlays; + config = { + allowUnfree = true; + joypixels.acceptLicense = true; + }; + }; + + nix = { + # Makes `nix run` commands use unfree + registry = lib.mkForce { + nixpkgs.flake = inputs.nixpkgs; + nixpkgs-stable.flake = inputs.nixpkgs-stable; + + # Allow running unfree packages with nix3 commands via `nix run unfree#steam` + unfree.flake = pkgs.callPackage lib.mkUnfreeNixpkgs {path = inputs.nixpkgs;}; + unfree-stable.flake = pkgs.callPackage lib.mkUnfreeNixpkgs {path = inputs.nixpkgs-stable;}; + }; + + # Disable channels + channel.enable = false; + # Force latest nix version + package = pkgs.nixVersions.nix_2_23; + + # Perform nix store optimisation weekly to maintain low disk usage + optimise = { + automatic = true; + dates = ["weekly"]; # Optional; allows customizing optimisation schedule + }; + + # Perform garbage collection weekly to maintain low disk usage + gc = { + automatic = true; + dates = "weekly"; + # Delete generations that are more than 14 days old + options = "--delete-older-than 14d"; + }; + + settings = { + # Make sure flakes is enabled + experimental-features = ["nix-command" "flakes"]; + + # No warnings if git isn't pushed + warn-dirty = false; + + # Force XDG Base Directory paths + use-xdg-base-directories = true; + + # for Nix path + nix-path = ["nixpkgs=${pkgs.path}"]; + + # Make root and any user in the wheel group trusted + trusted-users = ["root" "@wheel"]; + + substituters = [ + "https://nix-community.cachix.org" + "https://nix-gaming.cachix.org" + ]; + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + ]; + + # Reasonable defaults, see https://jackson.dev/post/nix-reasonable-defaults/ + connect-timeout = 5; + log-lines = 25; + min-free = 128000000; # 128MB + max-free = 1000000000; # 1GB + fallback = true; # If binary cache fails, it's okay + }; + }; + + documentation.nixos.enable = false; # Apparently speeds up rebuild time +} diff --git a/modules/core/security.nix b/modules/core/security.nix new file mode 100755 index 0000000..b4053ea --- /dev/null +++ b/modules/core/security.nix @@ -0,0 +1,42 @@ +_: { + # Make /tmp clean itself on remote. /tmp should be volatile storage! + boot.tmp.cleanOnBoot = true; + + boot.kernelModules = ["tcp_bbr"]; + + ## TCP hardening + boot.kernel.sysctl = { + # Prevent bogus ICMP errors from filling up logs. + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering causes the kernel to do source validation of + # packets received from all interfaces. This can mitigate IP spoofing. + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Do not accept IP source route packets (we're not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Don't send ICMP redirects (again, we're on a router) + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # Refuse ICMP redirects (MITM mitigations) + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # Protects against SYN flood attacks + "net.ipv4.tcp_syncookies" = 1; + # Incomplete protection again TIME-WAIT assassination + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # TCP Fast Open is a TCP extension that reduces network latency by packing + # data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for + # both incoming and outgoing connections: + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + slight improvement in throughput & latency + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; +} diff --git a/modules/core/user.nix b/modules/core/user.nix new file mode 100644 index 0000000..6c03a6b --- /dev/null +++ b/modules/core/user.nix @@ -0,0 +1,59 @@ +{ + config, + lib, + options, + username, + ... +}: let + internals = { + cfg = config.variables.user; + hostname = config.networking.hostName; + }; +in { + options.variables.user = { + fullName = lib.mkOption { + type = lib.types.str; + default = ""; + example = "John Doe"; + description = '' + Your first and last name. + ''; + }; + emailAddress = lib.mkOption { + type = lib.types.str; + default = ""; + example = "johndoe@example.com"; + description = '' + Your email address. + ''; + }; + homeDirectory = lib.mkOption { + type = lib.types.str; + description = '' + The directory for the user's folders. This should only be set if it's in a non-default location. + ''; + default = "/home/${username}"; + }; + }; + + config = { + #users.mutableUsers = false; # Makes it so we can only do password stuff via nixos, safer for not bricking system + + users.users.${username} = { + isNormalUser = true; + description = internals.cfg.fullName; + }; + + time = { + hardwareClockInLocalTime = lib.mkDefault true; + # Set UTC as default timezone, users can override if they want to + timeZone = lib.mkDefault "UTC"; + }; + + assertions = [ + #{assertion = options.variables.user.fullName.isDefined;} + #{assertion = options.variables.user.emailaddress.isDefined;} + {assertion = options.variables.user.homeDirectory.isDefined;} + ]; + }; +} diff --git a/modules/core/xdg.nix b/modules/core/xdg.nix new file mode 100644 index 0000000..a298127 --- /dev/null +++ b/modules/core/xdg.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: { + environment.sessionVariables = { + XDG_CACHE_HOME = "$HOME/.cache"; + XDG_CONFIG_HOME = "$HOME/.config"; + XDG_DATA_HOME = "$HOME/.local/share"; + XDG_STATE_HOME = "$HOME/.local/state"; + + ANDROID_USER_HOME = "$XDG_DATA_HOME/android"; + CUDA_CACHE_PATH = "$XDG_CACHE_HOME/nv"; + TLDR_CACHE_DIR = "$XDG_CACHE_HOME/tldr"; + }; +} diff --git a/programs/desktop/editors/default.nix b/modules/home/_editors/_default.nix similarity index 100% rename from programs/desktop/editors/default.nix rename to modules/home/_editors/_default.nix diff --git a/programs/desktop/editors/sublime.nix b/modules/home/_editors/_sublime.nix similarity index 100% rename from programs/desktop/editors/sublime.nix rename to modules/home/_editors/_sublime.nix diff --git a/programs/desktop/editors/vscode/default.nix b/modules/home/_editors/_vscode/_default.nix similarity index 100% rename from programs/desktop/editors/vscode/default.nix rename to modules/home/_editors/_vscode/_default.nix diff --git a/programs/desktop/editors/vscode/extensions.nix b/modules/home/_editors/_vscode/_extensions.nix similarity index 100% rename from programs/desktop/editors/vscode/extensions.nix rename to modules/home/_editors/_vscode/_extensions.nix diff --git a/programs/desktop/editors/vscode/settings.nix b/modules/home/_editors/_vscode/_settings.nix similarity index 100% rename from programs/desktop/editors/vscode/settings.nix rename to modules/home/_editors/_vscode/_settings.nix diff --git a/modules/home/comms/discord.nix b/modules/home/comms/discord.nix new file mode 100644 index 0000000..70e4d56 --- /dev/null +++ b/modules/home/comms/discord.nix @@ -0,0 +1,25 @@ +{ + config, + osConfig, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "discord" { + home.packages = with pkgs; + if (lib.conds.isWayland osConfig) + then [discord-wayland vesktop] + else [discord]; + + # make vesktop autostart properly + xdg.configFile."autostart/vesktop.desktop".text = '' + [Desktop Entry] + Type=Application + Version=1.0 + Name=Vencord + Comment=Vencord autostart script + Exec=sh -c "${pkgs.vesktop}/bin/vesktop --start-minimized" + Terminal=false + StartupNotify=false + ''; +} diff --git a/programs/desktop/apps.nix b/modules/home/comms/messengers.nix similarity index 80% rename from programs/desktop/apps.nix rename to modules/home/comms/messengers.nix index f257ad6..c20d33e 100644 --- a/programs/desktop/apps.nix +++ b/modules/home/comms/messengers.nix @@ -14,9 +14,5 @@ todoist-electron obs-studio - # Browsers - floorp - ungoogled-chromium - brave ]; } diff --git a/modules/home/defaults.nix b/modules/home/defaults.nix new file mode 100644 index 0000000..ab0094a --- /dev/null +++ b/modules/home/defaults.nix @@ -0,0 +1,47 @@ +{ + config, + osConfig, + lib, + ... +}: let + cfg = config.variables; +in { + options.variables = { + defaultTerminal = lib.mkOption { + default = + if osConfig.modules.desktop.enable + then (throw "defaultTerminal not set") + else null; + type = lib.types.str; + }; + + defaultBrowser = lib.mkOption { + default = + if osConfig.modules.desktop.enable + then (throw "defaultBrowser not set") + else null; + type = lib.types.str; + }; + + defaultTextEditor = lib.mkOption { + default = ""; + type = lib.types.str; + }; + }; + + config = lib.mkMerge [ + (lib.mkIf ((lib.conds.runsDesktop osConfig) && cfg.defaultTerminal != null) { + home.sessionVariables.TERMINAL = cfg.defaultTerminal; + + modules.${cfg.defaultTerminal}.enable = true; + }) + + (lib.mkIf ((lib.conds.runsDesktop osConfig) && cfg.defaultBrowser != null) { + modules.${cfg.defaultBrowser}.enable = true; + }) + + (lib.mkIf (cfg.defaultTextEditor != null) { + modules.${cfg.defaultTextEditor}.enable = true; + }) + ]; +} diff --git a/programs/development/default.nix b/modules/home/development/_default.nix similarity index 100% rename from programs/development/default.nix rename to modules/home/development/_default.nix diff --git a/programs/development/env/default.nix b/modules/home/development/_env/_default.nix similarity index 100% rename from programs/development/env/default.nix rename to modules/home/development/_env/_default.nix diff --git a/programs/development/env/paths.nix b/modules/home/development/_env/_paths.nix similarity index 100% rename from programs/development/env/paths.nix rename to modules/home/development/_env/_paths.nix diff --git a/programs/development/env/versions.nix b/modules/home/development/_env/_versions.nix similarity index 100% rename from programs/development/env/versions.nix rename to modules/home/development/_env/_versions.nix diff --git a/secrets/passwords/sudo.age b/modules/home/development/_languages/_default.nix similarity index 100% rename from secrets/passwords/sudo.age rename to modules/home/development/_languages/_default.nix diff --git a/programs/development/languages/go.nix b/modules/home/development/_languages/_go.nix similarity index 100% rename from programs/development/languages/go.nix rename to modules/home/development/_languages/_go.nix diff --git a/programs/development/languages/javascript.nix b/modules/home/development/_languages/_javascript.nix similarity index 100% rename from programs/development/languages/javascript.nix rename to modules/home/development/_languages/_javascript.nix diff --git a/programs/development/languages/python/default.nix b/modules/home/development/_languages/_python/_default.nix similarity index 100% rename from programs/development/languages/python/default.nix rename to modules/home/development/_languages/_python/_default.nix diff --git a/programs/development/languages/python/packages/repo-to-text.nix b/modules/home/development/_languages/_python/_packages/_repo-to-text.nix similarity index 100% rename from programs/development/languages/python/packages/repo-to-text.nix rename to modules/home/development/_languages/_python/_packages/_repo-to-text.nix diff --git a/programs/development/languages/rust.nix b/modules/home/development/_languages/_rust.nix similarity index 100% rename from programs/development/languages/rust.nix rename to modules/home/development/_languages/_rust.nix diff --git a/programs/development/tools/default.nix b/modules/home/development/_tools/_default.nix similarity index 100% rename from programs/development/tools/default.nix rename to modules/home/development/_tools/_default.nix diff --git a/programs/development/tools/direnv.nix b/modules/home/development/_tools/_direnv.nix similarity index 100% rename from programs/development/tools/direnv.nix rename to modules/home/development/_tools/_direnv.nix diff --git a/programs/development/tools/git.nix b/modules/home/development/_tools/_git.nix similarity index 100% rename from programs/development/tools/git.nix rename to modules/home/development/_tools/_git.nix diff --git a/modules/home/development/c.nix b/modules/home/development/c.nix new file mode 100644 index 0000000..f486b96 --- /dev/null +++ b/modules/home/development/c.nix @@ -0,0 +1,15 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "c" { + home.packages = with pkgs; [ + # :editor format + clang-tools + # :tools lsp + omnisharp-roslyn + gcc + ]; +} diff --git a/modules/home/development/java.nix b/modules/home/development/java.nix new file mode 100644 index 0000000..0580168 --- /dev/null +++ b/modules/home/development/java.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "java" { + programs.java.enable = true; + + home.sessionVariables.JDTLS_PATH = "${pkgs.jdt-language-server}/share/java"; + + home.packages = with pkgs; [ + # :tools lsp + java-language-server + + # :lang java + jdt-language-server + ]; +} diff --git a/modules/home/development/latex.nix b/modules/home/development/latex.nix new file mode 100644 index 0000000..40107ca --- /dev/null +++ b/modules/home/development/latex.nix @@ -0,0 +1,12 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "latex" { + home.packages = with pkgs; [ + # :editor format + texlive.combined.scheme-medium #LaTex + ]; +} diff --git a/modules/home/development/lua.nix b/modules/home/development/lua.nix new file mode 100644 index 0000000..11a5e65 --- /dev/null +++ b/modules/home/development/lua.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "lua" { + home.packages = with pkgs; [ + # :editor format + nodePackages.lua-fmt + # :tools lsp :lang lua + lua-language-server + ]; +} diff --git a/modules/home/development/markdown.nix b/modules/home/development/markdown.nix new file mode 100644 index 0000000..bf05f60 --- /dev/null +++ b/modules/home/development/markdown.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "markdown" { + home.packages = with pkgs; [ + # :lang markdown + proselint + pandoc + grip + ]; +} diff --git a/modules/home/development/nix.nix b/modules/home/development/nix.nix new file mode 100644 index 0000000..4db5d18 --- /dev/null +++ b/modules/home/development/nix.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + pkgs, + ... +}: let + alejandra-quiet = pkgs.writeShellScriptBin "alejandra-quiet" ''alejandra --quiet "$@"''; +in + lib.utilMods.mkModule config "nix" { + programs.nix-index-database.comma.enable = true; + + home.packages = with pkgs; [ + nh # Nice wrapper for NixOS and HM + alejandra # Nix formatter + nix-output-monitor # Monitor Nix compilation + nvd # Nix/NixOS package version diff tool + nixpkgs-review # Review nixpkgs + nurl # Automated prefetch tool for + nix-init # Automatically create nix packages from URLs + nix-inspect # View nix configurations + nil # Nix LSP + deadnix # Deadcode finder for NIx + statix # Anti-pattern detector + + alejandra-quiet # Wrapper for Emacs + ]; + } diff --git a/modules/home/development/python.nix b/modules/home/development/python.nix new file mode 100644 index 0000000..f99d7e2 --- /dev/null +++ b/modules/home/development/python.nix @@ -0,0 +1,31 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "python" { + programs.pyenv.enable = true; + + home.sessionVariables.PYENV_ROOT = "${config.xdg.dataHome}/pyenv"; + + home.sessionPath = ["${config.home.sessionVariables.PYENV_ROOT}/bin"]; + + home.packages = with pkgs; let + myPythonPackages = ps: + with ps; [ + debugpy + pyflakes + isort + pytest + black + pip + pipx + ]; + in [ + # :lang python, debugger, formatter + (python312.withPackages myPythonPackages) + pyright + pipenv + ]; +} diff --git a/modules/home/development/rust.nix b/modules/home/development/rust.nix new file mode 100644 index 0000000..be19ac9 --- /dev/null +++ b/modules/home/development/rust.nix @@ -0,0 +1,9 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "rust" { + home.packages = with pkgs; [rustup]; +} diff --git a/modules/home/development/web.nix b/modules/home/development/web.nix new file mode 100644 index 0000000..d295a57 --- /dev/null +++ b/modules/home/development/web.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "web" { + home.packages = with pkgs; [ + # :editor format + html-tidy + + # :lang web + stylelint + jsbeautifier + ]; +} diff --git a/modules/home/firefox/default.nix b/modules/home/firefox/default.nix new file mode 100644 index 0000000..434716e --- /dev/null +++ b/modules/home/firefox/default.nix @@ -0,0 +1,7 @@ +_: { + imports = [ + ./firefox.nix + ./floorp.nix + ./zen.nix + ]; +} diff --git a/modules/home/firefox/extensions.nix b/modules/home/firefox/extensions.nix new file mode 100644 index 0000000..3bd21d9 --- /dev/null +++ b/modules/home/firefox/extensions.nix @@ -0,0 +1,13 @@ +{pkgs, ...}: +with pkgs.nur.repos.rycee.firefox-addons; [ + ublock-origin + sponsorblock + return-youtube-dislikes + darkreader + #bypass-paywalls-clean + plasma-integration + enhancer-for-youtube + indie-wiki-buddy + stylus + canvasblocker +] diff --git a/modules/home/firefox/firefox.nix b/modules/home/firefox/firefox.nix new file mode 100644 index 0000000..98c860d --- /dev/null +++ b/modules/home/firefox/firefox.nix @@ -0,0 +1,62 @@ +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "firefox" { + xdg.mimeApps = let + defaultApplications = { + "default-web-browser" = ["firefox.desktop"]; + "text/html" = ["firefox.desktop"]; + "x-scheme-handler/http" = ["firefox.desktop"]; + "x-scheme-handler/https" = ["firefox.desktop"]; + "x-scheme-handler/about" = ["firefox.desktop"]; + "x-scheme-handler/unknown" = ["firefox.desktop"]; + "application/xhtml+xml" = ["firefox.desktop"]; + "text/xml" = ["firefox.desktop"]; + }; + in + lib.mkIf (config.variables.defaultBrowser == "firefox") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.firefox.enable = true; + + programs.firefox.nativeMessagingHosts = with pkgs; [fx-cast-bridge]; + + programs.firefox.profiles."${username}" = { + extensions = import ./extensions.nix {inherit pkgs;}; + + search = { + force = true; + default = "Ecosia"; + engines = import ./searchEngines.nix {inherit lib pkgs;}; + }; + + settings = { + "widget.use-xdg-desktop-portal.file-picker" = 1; + "browser.disableResetPrompt" = true; + "browser.download.panel.shown" = true; + "browser.download.useDownloadDir" = true; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.shell.checkDefaultBrowser" = true; + "browser.shell.defaultBrowserCheckCount" = 1; + "browser.startup.homepage" = "https://google.com"; + "browser.bookmarks.showMobileBookmarks" = true; + "dom.security.https_only_mode" = true; + "identity.fxaccounts.enabled" = true; + "privacy.trackingprotection.enabled" = true; + "signon.rememberSignons" = false; + "browser.newtabpage.pinned" = lib.singleton { + title = "NixOS"; + url = "https://nixos.org"; + }; + "browser.uiCustomization.state" = '' {"placements":{"widget-overflow-fixed-list":[],"unified-extensions-area":["privacy_privacy_com-browser-action","enhancerforyoutube_maximerf_addons_mozilla_org-browser-action","jid1-93cwpmrbvpjrqa_jetpack-browser-action","sponsorblocker_ajay_app-browser-action","_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action","_25cddbee-458b-4e9f-984d-dbf35511f124_-browser-action","canvasblocker_kkapsner_de-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_74145f27-f039-47ce-a470-a662b129930a_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_cb31ec5d-c49a-4e5a-b240-16c767444f62_-browser-action"],"nav-bar":["back-button","forward-button","stop-reload-button","home-button","firefox-view-button","urlbar-container","fxa-toolbar-menu-button","downloads-button","library-button","keepassxc-browser_keepassxc_org-browser-action","ublock0_raymondhill_net-browser-action","addon_darkreader_org-browser-action","plasma-browser-integration_kde_org-browser-action","_testpilot-containers-browser-action","unified-extensions-button","reset-pbm-toolbar-button","_3c078156-979c-498b-8990-85f7987dd929_-browser-action","browserpass_maximbaz_com-browser-action"],"toolbar-menubar":["menubar-items"],"TabsToolbar":["tabbrowser-tabs","new-tab-button","alltabs-button"],"PersonalToolbar":["import-button","personal-bookmarks"]},"seen":["save-to-pocket-button","developer-button","ublock0_raymondhill_net-browser-action","_testpilot-containers-browser-action","privacy_privacy_com-browser-action","addon_darkreader_org-browser-action","enhancerforyoutube_maximerf_addons_mozilla_org-browser-action","jid1-93cwpmrbvpjrqa_jetpack-browser-action","keepassxc-browser_keepassxc_org-browser-action","plasma-browser-integration_kde_org-browser-action","sponsorblocker_ajay_app-browser-action","_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action","browserpass_maximbaz_com-browser-action","_25cddbee-458b-4e9f-984d-dbf35511f124_-browser-action","canvasblocker_kkapsner_de-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_3c078156-979c-498b-8990-85f7987dd929_-browser-action","_74145f27-f039-47ce-a470-a662b129930a_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_cb31ec5d-c49a-4e5a-b240-16c767444f62_-browser-action"],"dirtyAreaCache":["nav-bar","PersonalToolbar","toolbar-menubar","TabsToolbar","widget-overflow-fixed-list","unified-extensions-area"],"currentVersion":20,"newElementCount":7} + ''; + }; + }; +} diff --git a/modules/home/firefox/floorp.nix b/modules/home/firefox/floorp.nix new file mode 100644 index 0000000..dc3af1d --- /dev/null +++ b/modules/home/firefox/floorp.nix @@ -0,0 +1,40 @@ +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "floorp" { + xdg.mimeApps = let + defaultApplications = { + "default-web-browser" = ["floorp.desktop"]; + "text/html" = ["floorp.desktop"]; + "x-scheme-handler/http" = ["floorp.desktop"]; + "x-scheme-handler/https" = ["floorp.desktop"]; + "x-scheme-handler/about" = ["floorp.desktop"]; + "x-scheme-handler/unknown" = ["floorp.desktop"]; + "application/xhtml+xml" = ["floorp.desktop"]; + "text/xml" = ["floorp.desktop"]; + }; + in + lib.mkIf (config.variables.defaultBrowser == "floorp") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.floorp.enable = true; + + programs.floorp.nativeMessagingHosts = with pkgs; [fx-cast-bridge kdePackages.plasma-browser-integration]; + + programs.floorp.profiles."${username}" = { + extensions = import ./extensions.nix {inherit pkgs;}; + + search = { + force = true; + default = "Ecosia"; + engines = import ./searchEngines.nix {inherit lib pkgs;}; + }; + }; +} diff --git a/modules/home/firefox/searchEngines.nix b/modules/home/firefox/searchEngines.nix new file mode 100644 index 0000000..94739ba --- /dev/null +++ b/modules/home/firefox/searchEngines.nix @@ -0,0 +1,71 @@ +{ + lib, + pkgs, + ... +}: let + nix-icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; +in { + "Ecosia" = { + iconUpdateURL = "https://www.ecosia.org/static/icons/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # Every day + definedAliases = ["@e" "@ecosia"]; + urls = lib.singleton {template = "https://www.ecosia.org/search?q={searchTerms}";}; + }; + + "Nix Packages" = { + inherit nix-icon; + definedAliases = lib.singleton "@np"; + urls = lib.singleton {template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}; + }; + + "NixOS Options" = { + inherit nix-icon; + definedAliases = lib.singleton "@no"; + urls = lib.singleton {template = "https://search.nixos.org/options?type=packages&query={searchTerms}";}; + }; + + "NixOS Wiki" = { + inherit nix-icon; + definedAliases = lib.singleton "@nw"; + urls = lib.singleton {template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}; + }; + + "Nixpkgs PR Tracker" = { + inherit nix-icon; + definedAliases = ["@nprt"]; + urls = lib.singleton {template = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";}; + }; + + # All these after all from llakala + "Noogle" = { + inherit nix-icon; + definedAliases = ["@nog"]; + urls = lib.singleton {template = "https://noogle.dev/q?term={searchTerms}";}; + }; + + "Nixpkgs" = { + iconUpdateURL = "https://github.com/favicon.ico"; + definedAliases = ["@npkgs"]; + urls = lib.singleton { + template = "https://github.com/search"; + # Thanks to xunuwu on github for being a reference to use of these functions + params = lib.attrsToList { + "type" = "code"; + "q" = "repo:NixOS/nixpkgs lang:nix {searchTerms}"; + }; + }; + }; + + "Github Nix Code" = { + iconUpdateURL = "https://github.com/favicon.ico"; + definedAliases = ["@ghn"]; + urls = lib.singleton { + template = "https://github.com/search"; + # Thanks to xunuwu on github for being a reference to use of these functions + params = lib.attrsToList { + "type" = "code"; + "q" = "lang:nix NOT is:fork {searchTerms}"; + }; + }; + }; +} diff --git a/modules/home/media/gaming.nix b/modules/home/media/gaming.nix new file mode 100644 index 0000000..1f5c4e4 --- /dev/null +++ b/modules/home/media/gaming.nix @@ -0,0 +1,454 @@ +{ + config, + lib, + pkgs, + username, + ... +}: let + cfg = config.modules.gaming; + hm-config = config.hm; +in + lib.utilMods.mkModule' config "gaming" { + minecraft-server.enable = lib.mkEnableOption "Enable minecraft server configs"; + vr.enable = lib.mkEnableOption "Enable virual reality configs"; + } (lib.mkMerge [ + # Minecraft + (lib.mkIf cfg.minecraft-server.enable { + # Allow Minecraft server ports + networking.firewall.allowedTCPPorts = [25565 24454]; + + hm.home.packages = with pkgs; [prismlauncher flite orca]; + hm.programs.java.enable = true; + hm.home.shellAliases = { + start-minecraft-server = "cd ~/Games/MinecraftServer-1.21.x/ && ./run.sh --nogui && cd || cd"; + start-minecraft-fabric-server = "cd ~/Games/MinecraftFabricServer-1.20.1/ && java -Xmx8G -jar ./fabric-server-mc.1.20.1-loader.0.15.7-launcher.1.0.0.jar nogui && cd || cd"; + }; + }) + # VR + (lib.mkIf cfg.vr.enable { + environment.systemPackages = with pkgs; [ + android-tools + android-udev-rules + BeatSaberModManager + helvum + ]; + + # Enable ALVR module on NixOS + programs.alvr.enable = true; + programs.alvr.openFirewall = true; + + # Fixes issue with SteamVR not starting + system.activationScripts.fixSteamVR = "${pkgs.libcap}/bin/setcap CAP_SYS_NICE+ep /home/${username}/.local/share/Steam/steamapps/common/SteamVR/bin/linux64/vrcompositor-launcher"; + + hm.xdg.desktopEntries = { + "BeatSaberModManager" = { + name = "Beat Saber ModManager"; + genericName = "Game"; + exec = "BeatSaberModManager"; + icon = "${pkgs.BeatSaberModManager}/lib/BeatSaberModManager/Resources/Icons/Icon.ico"; + type = "Application"; + categories = ["Game"]; + startupNotify = true; + comment = "Beat Saber ModManager is a mod manager for Beat Saber"; + }; + }; + }) + + # Common + { + # Enable Steam hardware compatibility + hardware.steam-hardware.enable = true; + + # Fixes SteamLink/Remote play crashing + environment.systemPackages = with pkgs; [protontricks keyutils goverlay ludusavi libcanberra protonup-qt]; + + environment.sessionVariables.ICED_BACKEND = "tiny-skia"; + hardware.graphics = { + enable = true; + enable32Bit = true; + }; + + programs.gamemode = { + enable = true; + enableRenice = true; + settings = { + general = { + softrealtime = "off"; + inhibit_screensaver = 1; + }; + custom = { + start = "''${pkgs.libnotify}/bin/notify-send 'GameMode started'"; + end = "''${pkgs.libnotify}/bin/notify-send 'GameMode ended'"; + }; + }; + }; + + programs.steam = { + enable = true; + # Make Steam folder spawn in ~/.config instead of /home/USER + package = pkgs.steam.override { + extraEnv.HOME = "/home/${username}/.config"; + extraLibraries = pkgs: [pkgs.xorg.libxcb]; + }; + remotePlay.openFirewall = true; + }; + + xdg.mime = { + defaultApplications."x-scheme-handler/steam" = "steam.desktop"; + addedAssociations."x-scheme-handler/steam" = "steam.desktop"; + }; + + hm.xdg = { + userDirs.extraConfig.XDG_GAME_DIR = "${hm-config.home.homeDirectory}/Games"; + + mimeApps = { + defaultApplications."x-scheme-handler/steam" = "steam.desktop"; + associations.added."x-scheme-handler/steam" = "steam.desktop"; + }; + }; + + hm.programs.mangohud = { + enable = true; + settings = { + ### From https://github.com/flightlessmango/MangoHud/blob/master/data/MangoHud.conf + ### MangoHud configuration file + ### Uncomment any options you wish to enable. Default options are left uncommented + ### Use some_parameter=0 to disable a parameter (only works with on/off parameters) + ### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead + + ################ INFORMATIONAL ################# + ## prints possible options on stdout + # help = true; + + ################ PERFORMANCE ################# + + ### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced) + # fps_limit = 0; + + ### early = wait before present, late = wait after present + # fps_limit_method = ""; + + ### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on + # vsync = -1; + + ### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N) + # gl_vsync = -2; + + ### Mip-map LoD bias. Negative values will increase texture sharpness (and aliasing) + ## Positive values will increase texture blurriness (-16 to 16) + # picmip = -17; + + ### Anisotropic filtering level. Improves sharpness of textures viewed at an angle (0 to 16) + # af = -1; + + ### Force bicubic filtering + # bicubic = true; + + ### Force trilinear filtering + # trilinear = true; + + ### Disable linear texture filtering. Makes textures look blocky + # retro = true; + + ################### VISUAL ################### + + ### Legacy layout + # legacy_layout = 0; + + ### pre defined presets + # -1 = default + # 0 = no display + # 1 = fps only + # 2 = horizontal view + # 3 = extended + # 4 = high detailed information + # preset = -1; + + ### Enable most of the toggleable parameters (currently excludes `histogram`) + # full = true; + + ### Show FPS only. ***Not meant to be used with other display params*** + # fps_only = true; + + ### Display custom centered text, useful for a header + # custom_text_center = ""; + + ### Display the current system time + # time = true; + + ### Time formatting examples + ## %H:%M + ## [ %T %F ] + ## %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese) + # time_format = "%T"; + + ### Display MangoHud version + # version = true; + + ### Display the current GPU information + ## Note: gpu_mem_clock and gpu_mem_temp also need "vram" to be enabled + gpu_stats = true; + gpu_temp = true; + # gpu_junction_temp = true; + # gpu_core_clock = true; + # gpu_mem_temp = true; + # gpu_mem_clock = true; + # gpu_power = true; + # gpu_text = ""; + gpu_load_change = true; + #gpu_load_value = [ "60" "90" ]; + #gpu_load_color = [ "39F900" "FDFD09" "B22222" ]; + ## GPU fan in rpm (only works on AMD GPUs) + # gpu_fan = true; + # gpu_voltage = true; # (only works on AMD GPUs) + + ### Display the current CPU information + cpu_stats = true; + cpu_temp = true; + # cpu_power = true; + # cpu_text = ""; + # cpu_mhz = true; + cpu_load_change = true; + #cpu_load_value = [ "60" "90" ]; + #cpu_load_color = [ "39F900" "FDFD09" "B22222" ]; + + ### Display the current CPU load & frequency for each core + # core_load = true; + # core_load_change = true; + + ### Display IO read and write for the app (not system) + # io_read = true; + # io_write = true; + + ### Display system vram / ram / swap space usage + vram = true; + ram = true; + # swap = true; + + ### Display per process memory usage + ## Show resident memory and other types, if enabled + # procmem = true; + # procmem_shared = true; + # procmem_virt = true; + + ### Display battery information + # battery = true; + # battery_icon = true; + # gamepad_battery = true; + # gamepad_battery_icon = true; + # battery_watt = true; + # battery_time = true; + + ### Display FPS and frametime + fps = true; + # fps_sampling_period = 500; + # fps_color_change = true; + # fps_value = ["30" "60"]; + # fps_color=["22222" "FDFD09" "39F900"]; + frametime = true; + # frame_count = true; + + ### Display GPU throttling status based on Power, current, temp or "other" + ## Only shows if throttling is currently happening + throttling_status = true; + + ### Display miscellaneous information + # engine_version = true; + # engine_short_names = true; + # gpu_name = true; + # vulkan_driver = true; + # wine = true; + # exec_name = true; + + ### Display loaded MangoHud architecture + # arch = true; + + ### Display the frametime line graph + frame_timing = true; + # histogram = true; + + ### Display GameMode / vkBasalt running status + # gamemode = true; + # vkbasalt = true; + + ### Gamescope related options + ## Display the status of FSR (only works in gamescope) + # fsr = true; + ## Hides the sharpness info for the `fsr` option (only available in gamescope) + # hide_fsr_sharpness = true; + ## Shows the graph of gamescope app frametimes and latency (only on gamescope obviously) + # debug = true; + + ### graphs displays one or more graphs that you chose + ## seperated by ",", available graphs are + ## gpu_load,cpu_load,gpu_core_clock,gpu_mem_clock,vram,ram,cpu_temp,gpu_temp + # graphs = [""]; + + ### mangoapp related options + ## Enables mangoapp to be displayed above the Steam UI + # mangoapp_steam = true; + + ### Steam Deck options + ## Shows the Steam Deck fan rpm + # fan = true; + + ### Display current FPS limit + show_fps_limit = true; + + ### Display the current resolution + # resolution = true; + + ### Display custom text + # custom_text = ""; + ### Display output of Bash command in next column + # exec = ""; + + ### Display media player metadata + # media_player = true; + ## for example spotify + # media_player_name = ""; + ## Format metadata, lines are delimited by ; (wip) + ## example: {title};{artist};{album} + ## example: Track:;{title};By:;{artist};From:;{album} + # media_player_format = ["title" "artist" "album"]; + + ### Change the hud font size + # font_size = 24; + # font_scale = 1.0; + # font_size_text = 24; + # font_scale_media_player = 0.55; + # no_small_font = true; + + ### Change default font (set location to TTF/OTF file) + ## Set font for the whole hud + # font_file = ""; + + ## Set font only for text like media player metadata + # font_file_text = ""; + + ## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these + ## Probably don't enable all at once because of memory usage and hardware limits concerns + ## If you experience crashes or text is just squares, reduce glyph range or reduce font size + # font_glyph_ranges = ["korean" "chinese" "chinese_simplified" "japanese" "cyrillic" "thai" "vietnamese" "latin_ext_a" "latin_ext_b"]; + + ### Outline text + text_outline = true; + # text_outline_color = 000000; + # text_outline_thickness = 1.5; + + ### Change the hud position + # position = "top-left"; + + ### Change the corner roundness + # round_corners = 0; + + ### Remove margins around MangoHud + # hud_no_margin = true; + + ### Display compact version of MangoHud + # hud_compact = true; + + ### Display MangoHud in a horizontal position + # horizontal = true; + # horizontal_stretch = true; + + ### Disable / hide the hud by default + # no_display = true; + + ### Hud position offset + # offset_x = 0; + # offset_y = 0; + + ### Hud dimensions + # width = 0; + # height = 140; + # table_columns = 3; + # cellpadding_y = -0.085; + + ### Hud transparency / alpha + # background_alpha = 0.5; + # alpha = 1.0; + + ### FCAT overlay + ### This enables an FCAT overlay to perform frametime analysis on the final image stream. + ### Enable the overlay + # fcat = true; + ### Set the width of the FCAT overlay. + ### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs. + ### A minimum of 20 pixels is recommended by nVidia. + # fcat_overlay_width = 24; + ### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise. + # fcat_screen_edge = 0; + + ### Color customization + # text_color = "FFFFFF"; + # gpu_color = "2E9762"; + # cpu_color = "2E97CB"; + # vram_color = "AD64C1"; + # ram_color = "C26693"; + # engine_color = "EB5B5B"; + # io_color = "A491D3"; + # frametime_color = "00FF00"; + # background_color = "020202"; + # media_player_color = "FFFFFF"; + # wine_color = "EB5B5B"; + # battery_color = "FF9078"; + + ### Specify GPU with PCI bus ID for AMDGPU and NVML stats + ### Set to 'domain:bus:slot.function' + # pci_dev = "0:0a:0.0"; + + ### Blacklist + # blacklist = ""; + + ### Control over socket + ### Enable and set socket name, '%p' is replaced with process id + ## example: mangohud + ## example: mangohud-%p + # control = -1; + + ################ WORKAROUNDS ################# + ### Options starting with "gl_*" are for OpenGL + ### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable + # gl_size_query = "viewport"; + + ### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III + # gl_bind_framebuffer = 0; + + ### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx + # gl_dont_flip = 1; + + ################ INTERACTION ################# + + ### Change toggle keybinds for the hud & logging + toggle_hud = "Shift_R+F12"; + # toggle_hud_position = "Shift_R+F11"; + # toggle_fps_limit = "Shift_L+F1"; + toggle_logging = "Shift_L+F2"; + # reload_cfg = "Shift_L+F4"; + # upload_log = "Shift_L+F3"; + + #################### LOG ##################### + ### Automatically start the log after X seconds + # autostart_log = ""; + ### Set amount of time in seconds that the logging will run for + # log_duration = ""; + ### Change the default log interval, 0 is default + # log_interval = 0; + ### Set location of the output files (required for logging) + output_folder = "${hm-config.xdg.stateHome}/mangologs"; + ### Permit uploading logs directly to FlightlessMango.com + ## set to 1 to enable + # permit_upload = 0; + ### Define a '+'-separated list of percentiles shown in the benchmark results + ### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1 + ## example: ['97', 'AVG', '1', '0.1'] + # benchmark_percentiles = ["97" "AVG"]; + ## Adds more headers and information such as versioning to the log. This format is not supported on flightlessmango.com (yet) + # log_versioning = true; + ## Enable automatic uploads of logs to flightlessmango.com + # upload_logs = true; + }; + }; + } + ]) diff --git a/modules/home/media/obs-studio.nix b/modules/home/media/obs-studio.nix new file mode 100644 index 0000000..dd2f3e7 --- /dev/null +++ b/modules/home/media/obs-studio.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "obs-studio" { + # Makes OBS Virtual Camera feature function + boot.extraModulePackages = with config.boot.kernelPackages; [v4l2loopback]; + + hm.programs.obs-studio.enable = true; + hm.programs.obs-studio.plugins = with pkgs.obs-studio-plugins; [ + obs-vkcapture + obs-pipewire-audio-capture + ]; +} diff --git a/modules/home/terminal/kitty.nix b/modules/home/terminal/kitty.nix new file mode 100644 index 0000000..b9e781c --- /dev/null +++ b/modules/home/terminal/kitty.nix @@ -0,0 +1,136 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "kitty" { + #modules.fonts.enable = true; + + xdg.mimeApps = let + defaultApplications = { + "mimetype" = "kitty.desktop"; + "application/x-terminal-emulator" = "kitty.desktop"; + "x-terminal-emulator" = "kitty.desktop"; + }; + in + lib.mkIf (config.variables.defaultTerminal == "kitty") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.kitty.enable = true; + + programs.kitty.environment = { + COLORTERM = "truecolor"; + WINIT_X11_SCALE_FACTOR = "1"; + }; + + programs.kitty.settings = { + # Advanced {{{ + term = "xterm-256color"; + #shell = "${pkgs.zsh}/bin/zsh --login --interactive"; + #kitty_mod = "ctrl+shift"; + #startup_session = "default.conf"; + repaint_delay = 0; + # }}} + + # Terminal Bell {{{ + enable_audio_bell = "yes"; + visual_bell_duration = "0.0"; + bell_on_tab = "🔔 "; + linux_bell_theme = "__ocean"; + bell_path = "${pkgs.kdePackages.ocean-sound-theme}/share/sounds/ocean/stereo/bell-window-system.oga"; + # }}} + + # Cursor {{{ + cursor_shape = "block"; + cursor_blink_interval = "0.5"; + # }}} + + # Scrollback {{{ + scrollback_lines = 5000; + # }}} + + # Mouse {{{ + show_hyperlink_targets = "yes"; + copy_on_select = "yes"; + paste_actions = "quote-urls-at-prompt,confirm-if-large"; + focus_follows_mouse = "yes"; + mouse_hide_wait = 0; + # }}} + + # Window Layout {{{ + remember_window_size = "yes"; + # FIXME: Add fonts for machine types + /* + initial_window_width = + if (config.variables.machine.buildType == "laptop") + then 1000 + else 1920; + initial_window_height = + if (config.variables.machine.buildType == "laptop") + then 700 + else 1080; + */ + + enabled_layouts = "tall:bias=65;full_size=1;mirrored=false"; + # }}} + + # Color Scheme {{{ + dynamic_background_opacity = "yes"; + # }}} + }; + programs.kitty.keybindings = { + #: Window management {{{ + #: New window + #"kitty_mod+enter" = "new_window"; + #"f7" = "focus_visible_window"; + #"f8" = "swap_with_window"; + + #"ctrl+left" = "resize_window narrower"; + #"ctrl+right" = "resize_window wider"; + #"ctrl+up" = "resize_window taller"; + #"ctrl+down" = "resize_window shorter"; + + # reset all windows in the tab to default sizes + #"kitty_mod+z" = "resize_window reset"; + + # }}} + + #: Tab Management {{{ + #"ctrl+t" = "new_tab"; + # }}} + + # Font Sizes {{{ + #: Increase font size + "ctrl+equal" = "change_font_size all +1.0"; + + #: Decrease font size + "ctrl+minus" = "change_font_size all -1.0"; + + "ctrl+0" = "change_font_size all 0"; + # }}} + + #: Miscellaneous {{{ + #: Show documentation + "f9" = "show_kitty_doc overview"; + + #: Toggle fullscreen + "f11" = "toggle_fullscreen"; + + #: Toggle maximized + "f10" = "toggle_maximized"; + + #: Edit config file + #"f2" = "launch --type=tab emacsclient -nw ~/.config/kitty/kitty.conf"; + + #: Reload kitty.conf + "f5" = "combine : load_config_file : launch --type=overlay --hold --allow-remote-control kitty @ send-text 'kitty config reloaded'"; + #"ctrl+r" = "combine : load_config_file : launch --type=overlay --hold --allow-remote-control kitty @ send-text 'kitty config reloaded'"; + #: Debug kitty configuration + "f6" = "debug_config"; + # }}} + }; +} diff --git a/modules/home/terminal/konsole.nix b/modules/home/terminal/konsole.nix new file mode 100644 index 0000000..1a38a0b --- /dev/null +++ b/modules/home/terminal/konsole.nix @@ -0,0 +1,23 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "konsole" { + xdg.mimeApps = let + defaultApplications = { + "mimetype" = "konsole.desktop"; + "application/x-terminal-emulator" = "konsole.desktop"; + "x-terminal-emulator" = "konsole.desktop"; + }; + in + lib.mkIf (config.variables.defaultTerminal == "konsole") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + # DefaultThemed profile is considered the Stylix module + programs.konsole.enable = true; +} diff --git a/modules/home/theme/common.nix b/modules/home/theme/common.nix new file mode 100644 index 0000000..1389609 --- /dev/null +++ b/modules/home/theme/common.nix @@ -0,0 +1,115 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) types mkOption literalExpression mkIf mkMerge mkBefore; + cfg = config.theme; + cfgapp = cfg.app; + + iconThemeModule = types.submodule { + options = { + package = mkOption { + type = types.nullOr types.package; + default = null; + example = literalExpression "pkgs.papirus-icon-theme"; + description = '' + Package providing the theme. This package will be installed to your profile. If 'null', then the theme is assumed to be already available in your profile. + ''; + }; + name = mkOption { + type = types.str; + default = ""; + example = "Papirus-Dark"; + description = "The symbolic name of the theme within the package without any spaces."; + }; + }; + }; + + appModule = types.submodule { + options = { + rio.name = mkOption { + type = types.str; + default = ""; + example = "3024 Night"; + description = '' + The name of the theme within the package to use for Rio. + + See theme names: https://github.com/raphamorim/rio-terminal-themes/tree/main/themes + ''; + }; + }; + }; +in { + options.theme = { + packages = mkOption { + type = types.listOf types.package; + default = []; + example = literalExpression "with pkgs; [ dracula-theme ]"; + description = '' + Packages providing the theme. The list of packages will be installed to your profile. If empty, then the theme is assumed to be already available in your profile. + ''; + }; + name = mkOption { + type = types.str; + default = ""; + example = "Dracula"; + description = "The name of the theme within the package."; + }; + nameSymbolic = mkOption { + type = types.str; + default = ""; + example = "dracula"; + description = "The symbolic name of the theme within the package without any spaces."; + }; + iconTheme = mkOption { + type = types.nullOr iconThemeModule; + default = {}; + description = "Icon configuration options."; + }; + app = mkOption { + type = types.nullOr appModule; + default = {}; + description = "App theme configuration options."; + }; + }; + + config = mkIf (cfg != null) (mkMerge [ + # Configure rio + (mkIf (cfgapp != null && config.programs.rio.enable) { + xdg.configFile."rio/themes/${cfgapp.rio.name}.toml".source = + fetchGit { + url = "https://github.com/raphamorim/rio-terminal-themes"; + rev = "9d76eb416c1cc46f959f236fdfa5479a19c0a070"; + } + + "/themes/${cfgapp.rio.name}.toml"; + programs.rio.settings = mkBefore { + # It makes Rio look for the specified theme in the themes folder + # (macos and linux: ~/.config/rio/themes/dracula.toml) + # (windows: C:\Users\USER\AppData\Local\rio\themes\dracula.toml) + theme = "${cfgapp.rio.name}"; + }; + }) + # Configure gtk theme + (mkIf config.gtk.enable { + gtk = { + iconTheme = mkIf (cfg.iconTheme != null) { + inherit (cfg.iconTheme) name; + inherit (cfg.iconTheme) package; + }; + }; + }) + + { + nukeFiles = ["${config.home.homeDirectory}/.config/gtk-2.0/gtkrc" "${config.home.homeDirectory}/.config/gtk-3.0/gtk.css" "${config.home.homeDirectory}/.config/gtk-4.0/gtk.css" "${config.home.homeDirectory}/.gtkrc-2.0"]; + programs.plasma.workspace.iconTheme = "${cfg.iconTheme.name}"; + # Install the packages + home.packages = with pkgs; (mkMerge + [ + (mkIf (cfg.packages != []) cfg.packages) + (mkIf (cfg.iconTheme.package != null) [cfg.iconTheme.package]) + ]); + } + ]); +} diff --git a/modules/home/theme/konsole.mustache b/modules/home/theme/konsole.mustache new file mode 100644 index 0000000..8f9c881 --- /dev/null +++ b/modules/home/theme/konsole.mustache @@ -0,0 +1,64 @@ +[Background] +Color={{base00-rgb-r}},{{base00-rgb-g}},{{base00-rgb-b}} + +[BackgroundIntense] +Color={{base03-rgb-r}},{{base03-rgb-g}},{{base03-rgb-b}} + +[Color0] +Color={{base00-rgb-r}},{{base00-rgb-g}},{{base00-rgb-b}} + +[Color0Intense] +Color={{base03-rgb-r}},{{base03-rgb-g}},{{base03-rgb-b}} + +[Color1] +Color={{base08-rgb-r}},{{base08-rgb-g}},{{base08-rgb-b}} + +[Color1Intense] +Color={{base08-rgb-r}},{{base08-rgb-g}},{{base08-rgb-b}} + +[Color2] +Color={{base0B-rgb-r}},{{base0B-rgb-g}},{{base0B-rgb-b}} + +[Color2Intense] +Color={{base0B-rgb-r}},{{base0B-rgb-g}},{{base0B-rgb-b}} + +[Color3] +Color={{base0A-rgb-r}},{{base0A-rgb-g}},{{base0A-rgb-b}} + +[Color3Intense] +Color={{base0A-rgb-r}},{{base0A-rgb-g}},{{base0A-rgb-b}} + +[Color4] +Color={{base0D-rgb-r}},{{base0D-rgb-g}},{{base0D-rgb-b}} + +[Color4Intense] +Color={{base0D-rgb-r}},{{base0D-rgb-g}},{{base0D-rgb-b}} + +[Color5] +Color={{base0E-rgb-r}},{{base0E-rgb-g}},{{base0E-rgb-b}} + +[Color5Intense] +Color={{base0E-rgb-r}},{{base0E-rgb-g}},{{base0E-rgb-b}} + +[Color6] +Color={{base0C-rgb-r}},{{base0C-rgb-g}},{{base0C-rgb-b}} + +[Color6Intense] +Color={{base0C-rgb-r}},{{base0C-rgb-g}},{{base0C-rgb-b}} + +[Color7] +Color={{base05-rgb-r}},{{base05-rgb-g}},{{base05-rgb-b}} + +[Color7Intense] +Color={{base07-rgb-r}},{{base07-rgb-g}},{{base07-rgb-b}} + +[Foreground] +Color={{base05-rgb-r}},{{base05-rgb-g}},{{base05-rgb-b}} + +[ForegroundIntense] +Color={{base07-rgb-r}},{{base07-rgb-g}},{{base07-rgb-b}} + +[General] +Description=Base16 {{scheme-name}} +Opacity=1 +Wallpaper= diff --git a/modules/home/theme/stylix.nix b/modules/home/theme/stylix.nix new file mode 100644 index 0000000..4463d6e --- /dev/null +++ b/modules/home/theme/stylix.nix @@ -0,0 +1,165 @@ +{ + config, + osConfig, + lib, + ... +}: let + cfg = config.theme.stylix; + c = config.lib.stylix.colors.withHashtag; + f = config.stylix.fonts; +in { + options.theme.stylix = { + enable = lib.mkEnableOption "Enable Stylix" // {default = osConfig.stylix.enable;}; + }; + + config = + lib.mkIf cfg.enable + (lib.mkMerge [ + (lib.mkIf (config.variables.defaultTerminal == "konsole") { + programs.konsole = { + defaultProfile = "DefaultThemed"; + profiles.DefaultThemed = { + name = "DefaultThemed"; + colorScheme = "Stylix"; + font = { + name = "${config.stylix.fonts.monospace.name}"; + size = config.stylix.fonts.sizes.terminal; + }; + }; + }; + + xdg = { + dataFile = { + "konsole/Stylix.colorscheme".source = config.lib.stylix.colors { + template = builtins.readFile ./konsole.mustache; + extension = ".colorscheme"; + }; + /* + "yakuake/skins/Dracula".source = fetchGit { + url = "https://github.com/dracula/yakuake"; + rev = "591a705898763167dd5aca2289d170f91a85aa56"; + }; + */ + }; + }; + }) + { + nukeFiles = ["${config.home.homeDirectory}/.config/gtk-2.0/gtkrc" "${config.home.homeDirectory}/.config/gtk-3.0/gtk.css" "${config.home.homeDirectory}/.config/gtk-4.0/gtk.css" "${config.home.homeDirectory}/.gtkrc-2.0"]; + + gtk = lib.mkIf (config.stylix.polarity == "dark") { + enable = true; + theme.name = lib.mkForce "adw-gtk3-dark"; + gtk3.extraConfig = {gtk-application-prefer-dark-theme = true;}; + gtk4.extraConfig = {gtk-application-prefer-dark-theme = true;}; + }; + + programs = { + rio.settings = { + window.opacity = config.stylix.opacity.terminal; + fonts = { + size = f.sizes.terminal + 3; # Make it larger because fonts are really tiny using default stylix font size + family = "${f.monospace.name}"; + emoji = { + family = "${f.emoji.name}"; + }; + }; + }; + plasma = { + overrideConfig = true; + workspace.cursor = { + theme = "${config.stylix.cursor.name}"; + inherit (config.stylix.cursor) size; + }; + fonts = let + general = { + family = "${f.sansSerif.name}"; + pointSize = f.sizes.applications; + }; + small = { + inherit (general) family; + pointSize = f.sizes.desktop; + }; + in { + inherit general small; + fixedWidth = { + family = "${f.monospace.name}"; + pointSize = f.sizes.terminal; + }; + toolbar = small; + menu = small; + windowTitle = small; + }; + }; + + zsh.syntaxHighlighting.styles = { + ## General + ### Diffs + ### Markup + ## Classes + # Comments + comment = "fg=${c.base04}"; + ## Constants + ## Entitites + ## Functions/methods + alias = "fg=${c.base0B}"; + suffix-alias = "fg=${c.base0B}"; + global-alias = "fg=${c.base0B}"; + function = "fg=${c.base0B}"; + command = "fg=${c.base0B}"; + precommand = "fg=${c.base0B},italic"; + autodirectory = "fg=${c.base09},italic"; + single-hyphen-option = "fg=${c.base09}"; + double-hyphen-option = "fg=${c.base09}"; + back-quoted-argument = "fg=${c.base0E}"; + ## Keywords + ## Built ins + builtin = "fg=${c.base0B}"; + reserved-word = "fg=${c.base0B}"; + hashed-command = "fg=${c.base0B}"; + ## Punctuation + commandseparator = "fg=${c.base08}"; + command-substitution-delimiter = "fg=${c.base05}"; + command-substitution-delimiter-unquoted = "fg=${c.base05}"; + process-substitution-delimiter = "fg=${c.base05}"; + back-quoted-argument-delimiter = "fg=${c.base08}"; + back-double-quoted-argument = "fg=${c.base08}"; + back-dollar-quoted-argument = "fg=${c.base08}"; + ## Serializable / Configuration Languages + ## Storage + ## Strings + command-substitution-quoted = "fg=${c.base0A}"; + command-substitution-delimiter-quoted = "fg=${c.base0A}"; + single-quoted-argument = "fg=${c.base0A}"; + single-quoted-argument-unclosed = "fg=${c.base08},bold"; + double-quoted-argument = "fg=${c.base0A}"; + double-quoted-argument-unclosed = "fg=${c.base08},bold"; + rc-quote = "fg=${c.base0A}"; + ## Variables + dollar-quoted-argument = "fg=${c.base05}"; + dollar-quoted-argument-unclosed = "fg=${c.base08},bold"; + dollar-double-quoted-argument = "fg=${c.base05}"; + assign = "fg=${c.base05}"; + named-fd = "fg=${c.base05}"; + numeric-fd = "fg=${c.base05}"; + ## No category relevant in spec + unknown-token = "fg=${c.base08},bold"; + path = "fg=${c.base05}"; + path_pathseparator = "fg=${c.base08}"; + path_prefix = "fg=${c.base05}"; + path_prefix_pathseparator = "fg=${c.base08}"; + globbing = "fg=${c.base05}"; + history-expansion = "fg=${c.base0E}"; + #command-substitution ="fg=?"; + #command-substitution-unquoted ="fg=?"; + #process-substitution ="fg=?"; + #arithmetic-expansion ="fg=?"; + back-quoted-argument-unclosed = "fg=${c.base08},bold"; + redirection = "fg=${c.base05}"; + arg0 = "fg=${c.base05}"; + default = "fg=${c.base05}"; + cursor = "fg=${c.base05}"; + }; + }; + } + ]); +} diff --git a/modules/home/virtualization/virtualization.nix b/modules/home/virtualization/virtualization.nix new file mode 100755 index 0000000..40d193d --- /dev/null +++ b/modules/home/virtualization/virtualization.nix @@ -0,0 +1,36 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "virtualization" { + # Enable dconf (System Management Tool) + #programs.dconf.enable = true; + + # Install necessary packages + environment.systemPackages = with pkgs; [ + virt-manager + virt-viewer + #spice + #spice-gtk + #spice-protocol + win-virtio + win-spice + guestfs-tools + libguestfs + ]; + + # Manage the virutalisation services + virtualisation.spiceUSBRedirection.enable = true; + virtualisation.libvirtd = { + enable = true; + qemu.swtpm.enable = true; + qemu.ovmf = { + enable = true; + packages = with pkgs; [OVMFFull.fd]; + }; + }; + + services.spice-vdagentd.enable = true; +} diff --git a/modules/home/virtualization/waydroid.nix b/modules/home/virtualization/waydroid.nix new file mode 100644 index 0000000..2ccf43c --- /dev/null +++ b/modules/home/virtualization/waydroid.nix @@ -0,0 +1,10 @@ +{ + pkgs, + lib, + config, + ... +}: +lib.utilMods.mkModule config "waydroid" { + virtualisation.waydroid.enable = true; + environment.systemPackages = with pkgs; [nur.repos.ataraxiasjel.waydroid-script]; +} diff --git a/secrets/passwords/tailscale.age b/profiles/default.nix similarity index 100% rename from secrets/passwords/tailscale.age rename to profiles/default.nix diff --git a/profiles/home/default.nix b/profiles/home/default.nix new file mode 100644 index 0000000..9a61ad5 --- /dev/null +++ b/profiles/home/default.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./comms + ./development + ./firefox + ./media + ./terminal + ./theme + ./virtualization + ./defaults.nix + ]; + + options.modules.home = { + profile = lib.mkOption { + type = lib.types.enum [ "minimal" "desktop" "gaming" "development" ]; + default = "minimal"; + description = "The home configuration profile to use"; + }; + }; +} diff --git a/profiles/home/desktop.nix b/profiles/home/desktop.nix new file mode 100644 index 0000000..2594d53 --- /dev/null +++ b/profiles/home/desktop.nix @@ -0,0 +1,22 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/home/firefox + ../../modules/home/theme + ../../modules/home/terminal + ]; + + modules = { + firefox.enable = true; + theme = { + enable = true; + stylix.enable = config.stylix.enable; + }; + terminal = { + kitty.enable = config.variables.defaultTerminal == "kitty"; + konsole.enable = config.variables.defaultTerminal == "konsole"; + }; + }; +} diff --git a/profiles/home/development.nix b/profiles/home/development.nix new file mode 100644 index 0000000..ceee956 --- /dev/null +++ b/profiles/home/development.nix @@ -0,0 +1,23 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./desktop.nix + ../../modules/home/development + ]; + + modules = { + development = { + enable = true; + languages = { + python.enable = true; + rust.enable = true; + nix.enable = true; + }; + tools = { + git.enable = true; + direnv.enable = true; + }; + }; + }; +} diff --git a/profiles/home/gaming.nix b/profiles/home/gaming.nix new file mode 100644 index 0000000..1e2eb17 --- /dev/null +++ b/profiles/home/gaming.nix @@ -0,0 +1,17 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./desktop.nix + ../../modules/home/media/gaming.nix + ]; + + modules = { + gaming = { + enable = true; + steam.enable = true; + minecraft.enable = false; # Enable as needed + vr.enable = false; # Enable as needed + }; + }; +} diff --git a/profiles/home/minimal.nix b/profiles/home/minimal.nix new file mode 100644 index 0000000..7f4912e --- /dev/null +++ b/profiles/home/minimal.nix @@ -0,0 +1,11 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../../modules/home/terminal/shell-basics.nix + ]; + + modules = { + terminal.basics.enable = true; + }; +} diff --git a/profiles/minimal.nix b/profiles/minimal.nix new file mode 100644 index 0000000..2041e87 --- /dev/null +++ b/profiles/minimal.nix @@ -0,0 +1,9 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../../modules/core/nix.nix + ../../modules/core/user.nix + ../../modules/core/security/hardening.nix + ]; +} diff --git a/profiles/server.nix b/profiles/server.nix new file mode 100644 index 0000000..4643547 --- /dev/null +++ b/profiles/server.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/core/security/ssh.nix + ]; + + modules = { + security = { + ssh.enable = true; + hardening = { + enable = true; + server = true; # Enable additional server hardening + }; + }; + }; +} diff --git a/profiles/workstation.nix b/profiles/workstation.nix new file mode 100644 index 0000000..c038ccf --- /dev/null +++ b/profiles/workstation.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/core/desktop.nix + ../../modules/core/security/gpg.nix + ../../modules/core/security/ssh.nix + ]; + + modules = { + desktop.enable = true; + security = { + gpg.enable = true; + ssh.enable = true; + }; + }; +} diff --git a/programs/core/security/ssh.nix b/programs/core/security/ssh.nix deleted file mode 100644 index 46ed8c8..0000000 --- a/programs/core/security/ssh.nix +++ /dev/null @@ -1,67 +0,0 @@ -{ config, pkgs, lib, ... }: - -{ - programs.ssh = { - enable = true; - - extraConfig = '' - AddKeysToAgent yes - UseKeychain yes - IdentitiesOnly yes - HashKnownHosts yes - # Set default identity file for all hosts - IdentityFile ~/.ssh/jeirmeister - ''; - - # For better security - serverAliveInterval = 60; - serverAliveCountMax = 2; - - # Manage known hosts - userKnownHostsFile = "~/.ssh/known_hosts"; - - # Common configuration for all jeir.lan hosts - matchBlocks = { - # Default for all hosts - "*" = { - identityFile = "~/.ssh/jeirmeister"; - compression = true; - serverAliveInterval = 60; - }; - - # Shared configuration for all machines in jeir.lan - "*.jeir.lan" = { - user = "root"; - identityFile = "~/.ssh/jeirmeister"; - }; - - # Individual machine configurations - "openwrt.jeir.lan" = { - hostname = "openwrt.jeir.lan"; - }; - "probabe.jeir.lan" = { - hostname = "probabe.jeir.lan"; - }; - "lenovobabe.jeir.lan" = { - hostname = "lenovobabe.jeir.lan"; - }; - "minibabe.jeir.lan" = { - hostname = "minibabe.jeir.lan"; - }; - "littlebabe.jeir.lan" = { - hostname = "littlebabe.jeir.lan"; - }; - "monsterbabe.jeir.lan" = { - hostname = "monsterbabe.jeir.lan"; - }; - }; - }; - - # Ensure SSH directory exists with correct permissions - home.file.".ssh/.keep".text = ""; - home.activation.sshPermissions = lib.hm.dag.entryAfter [ "writeBoundary" ] '' - chmod 700 ~/.ssh - chmod 600 ~/.ssh/jeirmeister - chmod 644 ~/.ssh/jeirmeister.pub - ''; -} diff --git a/programs/core/shell/zsh.nix b/programs/core/shell/zsh.nix deleted file mode 100644 index 526ce35..0000000 --- a/programs/core/shell/zsh.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ config, lib, pkgs, sharedAliases, ... }: - -{ - programs.zsh = { - enable = true; - autosuggestion.enable = true; - enableCompletion = true; - syntaxHighlighting.enable = true; - shellAliases = sharedAliases; - - oh-my-zsh = { - enable = true; - theme = "robbyrussell"; - plugins = [ - "git" # Adds many git aliases and functions - "docker" # Docker aliases and completion - "kubectl" # Kubernetes aliases and completion - "tmux" # Tmux integration and aliases - "fzf" # Fuzzy finder integration - "dirhistory" # Keyboard shortcuts for directory navigation - "history" # Command history searching - "copypath" # Copy current directory path - "copyfile" # Copy file contents - "extract" # Extract any archive format - ]; - }; - - initExtra = '' - # Add nix profile to PATH - export PATH=$HOME/.nix-profile/bin:$PATH - ''; - }; -} diff --git a/programs/desktop/default.nix b/programs/desktop/default.nix deleted file mode 100644 index 5fddc50..0000000 --- a/programs/desktop/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ config, pkgs, ... }: - -{ - imports = [ - ./editors - ./terminals - ./apps.nix - ]; -} diff --git a/programs/gaming/default.nix b/programs/gaming/default.nix deleted file mode 100644 index 5fc94e0..0000000 --- a/programs/gaming/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, pkgs, ... }: - -{ - imports = [ - ./vr - ]; -} diff --git a/programs/gaming/vr/default.nix b/programs/gaming/vr/default.nix deleted file mode 100644 index 01017ae..0000000 --- a/programs/gaming/vr/default.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ config, pkgs, ... }: - -{ - home.packages = with pkgs; [ - immersed - ]; - - systemd.user.services.immersed = { - Unit = { - Description = "Immersed VR Client"; - After = [ - "graphical-session.target" - "network.target" - ]; - PartOf = [ "graphical-session.target" ]; - Requires = [ "network.target" ]; - }; - - Service = { - Type = "simple"; - ExecStartPre = "${pkgs.coreutils}/bin/sleep 2"; # Give the video device time to initialize - ExecStart = "${pkgs.immersed}/bin/immersed"; - Environment = [ - "DISPLAY=:0" - "XDG_CURRENT_DESKTOP=KDE" # Since you're using Plasma - "QT_QPA_PLATFORM=xcb" # Force X11 mode for better compatibility - "XDG_RUNTIME_DIR=/run/user/1000" - "XDG_SESSION_TYPE=x11" # Force X11 mode - ]; - Restart = "on-failure"; - RestartSec = 5; - StandardOutput = "journal"; - StandardError = "journal"; - DevicePolicy = "auto"; - }; - - Install = { - WantedBy = [ "graphical-session.target" ]; - }; - }; - - # Create required directories - home.file.".local/share/immersed/.keep".text = ""; - home.file.".config/immersed/.keep".text = ""; -} diff --git a/programs/terminal/default.nix b/programs/terminal/default.nix deleted file mode 100644 index 39cbd50..0000000 --- a/programs/terminal/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ config, pkgs, ... }: - -{ - imports = [ - ./kitty.nix - ]; -} diff --git a/programs/terminal/kitty.nix b/programs/terminal/kitty.nix deleted file mode 100644 index 3e7228e..0000000 --- a/programs/terminal/kitty.nix +++ /dev/null @@ -1,61 +0,0 @@ -{ config, pkgs, ... }: - -{ - programs.kitty = { - enable = true; - settings = { - font_family = "JetBrains Mono"; - font_size = 12; - window_padding_width = 4; - background_opacity = "0.95"; - hide_window_decorations = "yes"; - tab_bar_style = "powerline"; - - # Dracula theme colors - foreground = "#F8F8F2"; - background = "#282A36"; - selection_foreground = "#ffffff"; - selection_background = "#44475a"; - url_color = "#8be9fd"; - cursor = "#f8f8f2"; - - # black - color0 = "#21222c"; - color8 = "#6272a4"; - - # red - color1 = "#ff5555"; - color9 = "#ff6e6e"; - - # green - color2 = "#50fa7b"; - color10 = "#69ff94"; - - # yellow - color3 = "#f1fa8c"; - color11 = "#ffffa5"; - - # blue - color4 = "#bd93f9"; - color12 = "#d6acff"; - - # magenta - color5 = "#ff79c6"; - color13 = "#ff92df"; - - # cyan - color6 = "#8be9fd"; - color14 = "#a4ffff"; - - # white - color7 = "#f8f8f2"; - color15 = "#ffffff"; - - # tab bar - active_tab_foreground = "#282a36"; - active_tab_background = "#f8f8f2"; - inactive_tab_foreground = "#282a36"; - inactive_tab_background = "#6272a4"; - }; - }; -} diff --git a/programs/terminal/tmux/default.nix b/programs/terminal/tmux/default.nix deleted file mode 100644 index 7486812..0000000 --- a/programs/terminal/tmux/default.nix +++ /dev/null @@ -1,135 +0,0 @@ -{ config, pkgs, ... }: - -{ - programs.tmux = { - enable = true; - clock24 = true; - baseIndex = 1; - escapeTime = 0; - terminal = "screen-256color"; - historyLimit = 50000; - keyMode = "vi"; - customPaneNavigationAndResize = true; - - plugins = with pkgs.tmuxPlugins; [ - { - plugin = sensible; - extraConfig = '' - # Set default shell to zsh - set -g default-command "${pkgs.zsh}/bin/zsh" - ''; - } - { - plugin = resurrect; - extraConfig = '' - set -g @resurrect-strategy-nvim 'session' - set -g @resurrect-capture-pane-contents 'on' - set -g @resurrect-dir '${config.xdg.dataHome}/tmux/resurrect' - bind C-s run-shell ${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/save.sh - bind C-r run-shell ${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/restore.sh - ''; - } - { - plugin = continuum; - extraConfig = '' - set -g @continuum-restore 'on' - set -g @continuum-save-interval '15' - set -g @continuum-boot 'on' - ''; - } - { - plugin = better-mouse-mode; - extraConfig = '' - set -g @scroll-speed-num-lines-per-scroll 1 - ''; - } - { - plugin = yank; - extraConfig = '' - set -g @yank_selection 'clipboard' - set -g @yank_selection_mouse 'clipboard' - ''; - } - { - plugin = pain-control; - extraConfig = '' - bind C-h select-pane -L - bind C-j select-pane -D - bind C-k select-pane -U - bind C-l select-pane -R - ''; - } - { - plugin = sidebar; - extraConfig = '' - set -g @sidebar-tree-command 'tree -C' - bind Tab run-shell ${pkgs.tmuxPlugins.sidebar}/share/tmux-plugins/sidebar/scripts/toggle.sh - bind BSpace run-shell ${pkgs.tmuxPlugins.sidebar}/share/tmux-plugins/sidebar/scripts/toggle.sh - ''; - } - { - plugin = online-status; - extraConfig = '' - set -g @online_icon "✓" - set -g @offline_icon "✗" - ''; - } - { - plugin = cpu; - extraConfig = '' - set -g @cpu_percentage_format "%3.0f%%" - ''; - } - { - plugin = battery; - extraConfig = '' - set -g @battery_percentage_format "%3.0f%%" - ''; - } - { - plugin = fzf-url; - extraConfig = '' - set -g @fzf-url-bind 'u' - ''; - } - { - plugin = logging; - extraConfig = '' - set -g @logging-path "${config.xdg.dataHome}/tmux/logging" - bind P pipe-pane -o "cat >>#{@logging-path}/tmux-#W.log" \; display "Toggled logging to #{@logging-path}/tmux-#W.log" - ''; - } - { - plugin = fingers; - extraConfig = '' - set -g @fingers-key f - set -g @fingers-pattern-0 '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}' - ''; - } - ]; - - extraConfig = '' - # Set prefix - unbind C-b - set -g prefix C-a - bind C-a send-prefix - - # Mouse support - set -g mouse on - - # Status bar configuration - set -g status-interval 1 - set -g status-position top - set -g status-justify left - set -g status-left "#{online_status} #[fg=green]#S #[fg=yellow]#I #[fg=cyan]#P" - set -g status-right "#{cpu_fg_color}#{cpu_percentage} #[fg=colour136]#{battery_percentage} %H:%M:%S" - - # Natural language command bindings - bind : command-prompt -p "Command:" { - if -F "#{m:save-session,%%}" "run-shell ${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/save.sh" \ - if -F "#{m:restore-session,%%}" "run-shell ${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/restore.sh" \ - if -F "#{m:yank-text,%%}" "run-shell 'tmux show-buffer | ${pkgs.xclip}/bin/xclip -selection clipboard'" - } - ''; - }; -} diff --git a/programs/terminal/tmux/tmux-man.md b/programs/terminal/tmux/tmux-man.md deleted file mode 100644 index b674a7f..0000000 --- a/programs/terminal/tmux/tmux-man.md +++ /dev/null @@ -1,56 +0,0 @@ -% TMUX-PLUGINS(1) Custom Tmux Plugins Help | November 2024 - -# NAME -tmux-plugins - Overview of custom Tmux plugins, keybindings, and natural language commands - -# SYNOPSIS -This man page provides an overview of custom Tmux plugins, their purpose, example usage, and natural language commands. - -# PREFIX KEY -The prefix key for all tmux commands is `Ctrl-a` (C-a). This means whenever you see `Prefix + key`, you should: -1. Press and hold `Ctrl`, then press `a` -2. Release both keys -3. Press the specified key - -# DESCRIPTION -The following is a list of Tmux plugins installed through Home Manager in your environment, along with their purpose, example usage, and custom commands. - -# PLUGINS - -## 1. Sensible -- **Purpose**: Provides a set of sensible default configurations for tmux. -- **Example Usage**: - - Automatically enabled with better key bindings and options - - Uses zsh as the default shell - -## 2. Resurrect -- **Purpose**: Saves and restores your Tmux sessions, including windows, panes, and running processes. -- **Example Usage**: - - Save session: `Prefix + Ctrl-s` - - Restore session: `Prefix + Ctrl-r` -- **Natural Language Command**: - - `save-session`: Saves the current session. - - `restore-session`: Restores the last saved session. - -[rest of plugins remain the same until NATURAL LANGUAGE COMMANDS section] - -# NATURAL LANGUAGE COMMANDS - -In addition to keybindings, you can use these natural language commands from within tmux: - -1. `save-session`: Saves the current tmux session using Resurrect. -2. `restore-session`: Restores the last saved tmux session using Resurrect. -3. `yank-text`: Copies selected text to the system clipboard using Yank. - -These commands can be typed directly into tmux's command prompt (`Prefix + :`) or used as shell aliases. - -Note: Plugin management is handled through Home Manager, so there's no need for manual plugin installation or updates. - -# QUICK REFERENCE -You can access this manual at any time by typing `tmux-help` in your terminal. - -# SEE ALSO -tmux(1), man(1) - -# AUTHOR -Custom man page created for user-defined Tmux configuration with natural language commands. \ No newline at end of file diff --git a/proposal.md b/proposal.md deleted file mode 100644 index 06d0af1..0000000 --- a/proposal.md +++ /dev/null @@ -1,38 +0,0 @@ -. -├── flake.nix -├── lib # Helper functions -│ ├── default.nix -│ ├── mkHome.nix # Home configuration builder -│ └── mkHost.nix # Host configuration builder -├── hosts -│ └── steamnix # Your Steam Deck configuration -│ ├── configuration.nix -│ ├── hardware-configuration.nix -│ └── default.nix -├── modules -│ ├── core # Essential system modules -│ │ ├── default.nix -│ │ ├── nix.nix # Nix configuration -│ │ └── security.nix # Security settings -│ ├── home # Home-manager modules -│ │ ├── development -│ │ ├── desktop -│ │ └── terminal -│ └── system # System-level modules -│ ├── hardware -│ └── services -├── overlays # Custom package modifications -│ └── default.nix -├── profiles # Reusable configuration profiles -│ ├── desktop -│ │ └── plasma -│ ├── development -│ └── gaming -├── scripts # Maintenance scripts -│ └── rebuild.sh -├── secrets # Encrypted secrets management -│ └── default.nix -└── users - └── jeirmeister - ├── home.nix - └── config # User-specific configurations \ No newline at end of file diff --git a/repo_overview.txt b/repo_overview.txt new file mode 100644 index 0000000..0252f57 --- /dev/null +++ b/repo_overview.txt @@ -0,0 +1,7519 @@ +Directory: home-manager + +Directory Structure: +``` +. +├── .gitignore +├── flake.nix +├── hosts +│   ├── hosts/common +│   │   └── hosts/common/default.nix +│   ├── hosts/default.nix +│   └── hosts/steamnix +│   ├── hosts/steamnix/configuration.nix +│   ├── hosts/steamnix/default.nix +│   └── hosts/steamnix/hardware-configuration.nix +├── lib +│   ├── lib/conds.nix +│   ├── lib/default.nix +│   ├── lib/mkHome.nix +│   ├── lib/mkHost.nix +│   ├── lib/secrets.nix +│   └── lib/utils.nix +│   ├── modules/core +│   │   ├── modules/core/age.nix +│   │   ├── modules/core/default.nix +│   │   ├── modules/core/desktop.nix +│   │   ├── modules/core/filesystem.nix +│   │   ├── modules/core/home-manager.nix +│   │   ├── modules/core/ld.nix +│   │   ├── modules/core/networking.nix +│   │   ├── modules/core/nix.nix +│   │   ├── modules/core/_security +│   │   │   ├── modules/core/_security/default.nix +│   │   │   ├── modules/core/_security/gpg.nix +│   │   │   ├── modules/core/_security/hardening.nix +│   │   │   └── modules/core/_security/ssh.nix +│   │   ├── modules/core/security.nix +│   │   ├── modules/core/user.nix +│   │   └── modules/core/xdg.nix +│   └── modules/home +│   ├── modules/home/comms +│   │   ├── modules/home/comms/discord.nix +│   │   └── modules/home/comms/messengers.nix +│   ├── modules/home/defaults.nix +│   ├── modules/home/development +│   │   ├── modules/home/development/c.nix +│   │   ├── modules/home/development/_default.nix +│   │   ├── modules/home/development/_env +│   │   │   ├── modules/home/development/_env/_default.nix +│   │   │   ├── modules/home/development/_env/_paths.nix +│   │   │   └── modules/home/development/_env/_versions.nix +│   │   ├── modules/home/development/java.nix +│   │   ├── modules/home/development/_languages +│   │   │   ├── modules/home/development/_languages/_default.nix +│   │   │   ├── modules/home/development/_languages/_go.nix +│   │   │   ├── modules/home/development/_languages/_javascript.nix +│   │   │   ├── modules/home/development/_languages/_python +│   │   │   │   ├── modules/home/development/_languages/_python/_default.nix +│   │   │   │   └── modules/home/development/_languages/_python/_packages +│   │   │   │   └── modules/home/development/_languages/_python/_packages/_repo-to-text.nix +│   │   │   └── modules/home/development/_languages/_rust.nix +│   │   ├── modules/home/development/latex.nix +│   │   ├── modules/home/development/lua.nix +│   │   ├── modules/home/development/markdown.nix +│   │   ├── modules/home/development/nix.nix +│   │   ├── modules/home/development/python.nix +│   │   ├── modules/home/development/rust.nix +│   │   ├── modules/home/development/_tools +│   │   │   ├── modules/home/development/_tools/_default.nix +│   │   │   ├── modules/home/development/_tools/_direnv.nix +│   │   │   └── modules/home/development/_tools/_git.nix +│   │   └── modules/home/development/web.nix +│   ├── modules/home/_editors +│   │   ├── modules/home/_editors/_default.nix +│   │   ├── modules/home/_editors/_sublime.nix +│   │   └── modules/home/_editors/_vscode +│   │   ├── modules/home/_editors/_vscode/_default.nix +│   │   ├── modules/home/_editors/_vscode/_extensions.nix +│   │   └── modules/home/_editors/_vscode/_settings.nix +│   ├── modules/home/firefox +│   │   ├── modules/home/firefox/default.nix +│   │   ├── modules/home/firefox/extensions.nix +│   │   ├── modules/home/firefox/firefox.nix +│   │   ├── modules/home/firefox/floorp.nix +│   │   └── modules/home/firefox/searchEngines.nix +│   ├── modules/home/media +│   │   ├── modules/home/media/gaming.nix +│   │   └── modules/home/media/obs-studio.nix +│   ├── modules/home/terminal +│   │   ├── modules/home/terminal/kitty.nix +│   │   └── modules/home/terminal/konsole.nix +│   ├── modules/home/theme +│   │   ├── modules/home/theme/common.nix +│   │   ├── modules/home/theme/konsole.mustache +│   │   └── modules/home/theme/stylix.nix +│   └── modules/home/virtualization +│   ├── modules/home/virtualization/virtualization.nix +│   └── modules/home/virtualization/waydroid.nix +├── profiles +│   ├── profiles/default.nix +│   ├── profiles/home +│   │   ├── profiles/home/default.nix +│   │   ├── profiles/home/desktop.nix +│   │   ├── profiles/home/development.nix +│   │   ├── profiles/home/gaming.nix +│   │   └── profiles/home/minimal.nix +│   ├── profiles/minimal.nix +│   ├── profiles/server.nix +│   └── profiles/workstation.nix +├── README.md +├── secrets +│   ├── secrets/default.nix +│   ├── secrets/secrets.nix +│   └── secrets/users +│   ├── secrets/users/default.nix +│   ├── secrets/users/jeirmeister +│   │   ├── secrets/users/jeirmeister/default.nix +│   │   │   ├── secrets/users/jeirmeister/_keys/_gpg +│   │   │   │   ├── secrets/users/jeirmeister/_keys/_gpg/_private.key +│   │   │   │   └── secrets/users/jeirmeister/_keys/_gpg/_public.key +│   │   │   └── secrets/users/jeirmeister/_keys/_ssh +│   │   │   ├── secrets/users/jeirmeister/_keys/_ssh/_id_ed25519 +│   │   │   └── secrets/users/jeirmeister/_keys/_ssh/_id_ed25519.pub +│   │   └── secrets/users/jeirmeister/passwords +│   │   ├── secrets/users/jeirmeister/passwords/_bitwarden.age +│   │   ├── secrets/users/jeirmeister/passwords/_sudo.age +│   │   └── secrets/users/jeirmeister/passwords/_tailscale.age +│   └── secrets/users/jeirmeister.nix +├── system +│   ├── system/boot +│   │   ├── system/boot/default.nix +│   │   ├── system/boot/quietboot.nix +│   │   └── system/boot/systemd-boot.nix +│   ├── system/default.nix +│   ├── system/desktop +│   │   ├── system/desktop/appimage.nix +│   │   ├── system/desktop/default.nix +│   │   ├── system/desktop/_plasma6.nix +│   │   └── system/desktop/plasma6.nix +│   ├── system/hardware +│   │   ├── system/hardware/bluetooth.nix +│   │   ├── system/hardware/hardware-acceleration.nix +│   │   ├── system/hardware/qmk.nix +│   │   └── system/hardware/rgb.nix +│   ├── system/locales +│   │   └── system/locales/us-english.nix +│   ├── system/services +│   │   ├── system/services/flatpak.nix +│   │   ├── system/services/printing.nix +│   │   ├── system/services/sunshine.nix +│   │   ├── system/services/syncthing.nix +│   │   └── system/services/tailscale.nix +│   └── system/shell +│   ├── system/shell/aliases.nix +│   ├── system/shell/atuin.nix +│   ├── system/shell/bash.nix +│   ├── system/shell/bat.nix +│   ├── system/shell/cava.nix +│   ├── system/shell/default.nix +│   ├── system/shell/pass.nix +│   ├── system/shell/shell-utils.nix +│   ├── system/shell/tmux.nix +│   └── system/shell/zsh.nix + └── users/jeirmeister + ├── users/jeirmeister/config + │   ├── users/jeirmeister/config/git.nix + │   ├── users/jeirmeister/config/kde6 + │   │   ├── users/jeirmeister/config/kde6/common.nix + │   │   └── users/jeirmeister/config/kde6/panels.nix + │   ├── users/jeirmeister/config/pass.nix + │   ├── users/jeirmeister/config/ssh.nix + │   ├── users/jeirmeister/config/theme.nix + │   ├── users/jeirmeister/config/virt-manager.nix + │   ├── users/jeirmeister/config/vr.nix + │   └── users/jeirmeister/config/zsh.nix + │   ├── users/jeirmeister/dotfiles/alvr + │   │   ├── users/jeirmeister/dotfiles/alvr/active_runtime.json + │   │   └── users/jeirmeister/dotfiles/alvr/session.json + │   ├── users/jeirmeister/dotfiles/kitty + │   │   └── users/jeirmeister/dotfiles/kitty/default.conf + │   ├── users/jeirmeister/dotfiles/openrgb + │   │   ├── users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json + │   │   └── users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json + │   └── users/jeirmeister/dotfiles/tmuxp + │   └── users/jeirmeister/dotfiles/tmuxp/session.yaml + ├── users/jeirmeister/monsterbabe.nix + ├── users/jeirmeister/steamdeck.nix + └── users/jeirmeister/system.nix +``` + +Contents of flake.nix: +``` +{ + description = "Jeirmeister's NixOS Configuration"; + + nixConfig = { + extra-substituters = [ + "https://nix-gaming.cachix.org" + "https://nix-community.cachix.org" + ]; + extra-trusted-public-keys = [ + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + }; + + inputs = { + # Core dependencies + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11"; + + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # System dependencies + systems.url = "github:nix-systems/default"; + + # Additional tools + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Gaming-specific inputs + nix-gaming = { + url = "github:fufexan/nix-gaming"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, home-manager, ... } @ inputs: + let + lib = nixpkgs.lib.extend + (final: prev: import ./lib { inherit inputs self; lib = final; }); + + # Helper function to create specialized system configs + mkSystem = hostName: system: username: + lib.mkHost { + inherit system username hostName; + extraModules = [ + # Add your host-specific modules here + ]; + }; + + # Helper function to create home-manager configs + mkHome = username: hostName: + lib.mkHome { + inherit username hostName; + profiles = [ "desktop" "development" "gaming" ]; + }; + in + { + # NixOS configurations + nixosConfigurations = { + steamnix = mkSystem "steamnix" "x86_64-linux" "jeirmeister"; + }; + + # Home-manager configurations + homeConfigurations = { + "jeirmeister@steamnix" = mkHome "jeirmeister" "steamnix"; + }; + + # Formatter configuration + formatter = lib.forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt); + }; +} + +``` + +Contents of profiles/server.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/core/security/ssh.nix + ]; + + modules = { + security = { + ssh.enable = true; + hardening = { + enable = true; + server = true; # Enable additional server hardening + }; + }; + }; +} + +``` + +Contents of profiles/workstation.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/core/desktop.nix + ../../modules/core/security/gpg.nix + ../../modules/core/security/ssh.nix + ]; + + modules = { + desktop.enable = true; + security = { + gpg.enable = true; + ssh.enable = true; + }; + }; +} + +``` + +Contents of profiles/minimal.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../../modules/core/nix.nix + ../../modules/core/user.nix + ../../modules/core/security/hardening.nix + ]; +} + +``` + +Contents of profiles/default.nix: +``` + +``` + +Contents of profiles/home/desktop.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./minimal.nix + ../../modules/home/firefox + ../../modules/home/theme + ../../modules/home/terminal + ]; + + modules = { + firefox.enable = true; + theme = { + enable = true; + stylix.enable = config.stylix.enable; + }; + terminal = { + kitty.enable = config.variables.defaultTerminal == "kitty"; + konsole.enable = config.variables.defaultTerminal == "konsole"; + }; + }; +} + +``` + +Contents of profiles/home/minimal.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ../../modules/home/terminal/shell-basics.nix + ]; + + modules = { + terminal.basics.enable = true; + }; +} + +``` + +Contents of profiles/home/development.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./desktop.nix + ../../modules/home/development + ]; + + modules = { + development = { + enable = true; + languages = { + python.enable = true; + rust.enable = true; + nix.enable = true; + }; + tools = { + git.enable = true; + direnv.enable = true; + }; + }; + }; +} + +``` + +Contents of profiles/home/gaming.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./desktop.nix + ../../modules/home/media/gaming.nix + ]; + + modules = { + gaming = { + enable = true; + steam.enable = true; + minecraft.enable = false; # Enable as needed + vr.enable = false; # Enable as needed + }; + }; +} + +``` + +Contents of profiles/home/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./comms + ./development + ./firefox + ./media + ./terminal + ./theme + ./virtualization + ./defaults.nix + ]; + + options.modules.home = { + profile = lib.mkOption { + type = lib.types.enum [ "minimal" "desktop" "gaming" "development" ]; + default = "minimal"; + description = "The home configuration profile to use"; + }; + }; +} + +``` + +Contents of hosts/default.nix: +``` + +``` + +Contents of hosts/steamnix/configuration.nix: +``` +{ pkgs, lib, ... }: + +let + jovianNixosRev = "f6423d86bec22c25a576b23262495c5536b0d069"; + jovianNixos = builtins.fetchTarball { + url = "https://github.com/Jovian-Experiments/Jovian-NixOS/archive/${jovianNixosRev}.tar.gz"; + sha256 = "sha256:1frd1dfqd97idwf1rj29ab0wvyfa2nx2h3bp9hkbmfa1m802avmb"; + }; + + v4l2loopback-options = { + options = { + exclusive_caps = 1; + video_nr = 0; + card_label = "Immersed Virtual Camera"; + }; + }; +in +{ + imports = [ + ./hardware-configuration.nix + (jovianNixos + "/modules") + ]; + + # Basic System Configuration + system.stateVersion = "24.05"; + networking = { + hostName = "steamnix"; + networkmanager.enable = true; + }; + time.timeZone = "America/Los_Angeles"; + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + }; + + # Nix Package Manager Configuration + nixpkgs = { + overlays = [ + (import (jovianNixos + "/overlay.nix")) + ]; + config.allowUnfree = true; + }; + + nix.settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + substituters = [ "cache.nixos.org" ]; + allowed-users = [ + "@wheel" + "jeirmeister" + ]; + auto-optimise-store = true; + }; + + # Steam Deck Specific Configuration + jovian = { + hardware.has.amd.gpu = true; + devices.steamdeck = { + enable = true; + enableControllerUdevRules = true; + enableDefaultStage1Modules = true; + enablePerfControlUdevRules = true; + enableOsFanControl = true; + enableSoundSupport = true; + enableXorgRotation = true; + enableKernelPatches = true; + enableFwupdBiosUpdates = false; + autoUpdate = false; + }; + steam.enable = false; + workarounds.ignoreMissingKernelModules = true; + }; + + # Hardware and Display Configuration + hardware.video = { + displaylink.enable = true; + }; + + # Desktop Environment and Display Configuration + services.xserver = { + enable = true; + xkb.layout = "us"; + videoDrivers = [ + "displaylink" + "modesetting" + ]; + desktopManager.plasma6 = { + enable = true; + extraSessionCommands = '' + ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0; + ''; + }; + displayManager = { + sddm = { + enable = true; + wayland = true; + }; + sessionCommands = '' + ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0 + ''; + }; + }; + + # System Services Configuration + services = { + # Audio Configuration + pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; + }; + + # Network Services + openssh = { + enable = true; + settings = { + PasswordAuthentication = true; + AllowUsers = [ "jeirmeister" ]; + }; + }; + tailscale.enable = true; + }; + + # Systemd Services + systemd.services = { + jupiter-fan-control = { + path = [ pkgs.dmidecode ]; + serviceConfig = lib.mkForce { + Environment = "PYTHONUNBUFFERED=1"; + StandardOutput = "journal"; + StandardError = "journal"; + ExecStart = "${pkgs.jupiter-fan-control}/share/jupiter-fan-control/fancontrol.py --run"; + ExecStopPost = "${pkgs.jupiter-fan-control}/share/jupiter-fan-control/fancontrol.py --stop"; + OOMScoreAdjust = -1000; + Restart = "on-failure"; + }; + }; + + "systemd-modules-load" = { + wantedBy = [ "multi-user.target" ]; + restartIfChanged = true; + }; + }; + + # UDev Rules + services.udev.extraRules = '' + SUBSYSTEM=="hwmon*", KERNEL=="hwmon*", ACTION=="add", RUN+="${pkgs.coreutils}/bin/chmod a+rw /sys/%p/pwm1" + SUBSYSTEM=="hwmon*", KERNEL=="hwmon*", ACTION=="add", RUN+="${pkgs.coreutils}/bin/chmod a+rw /sys/%p/fan1_input" + ''; + + # User Configuration + users = { + users.jeirmeister = { + isNormalUser = true; + description = "jeirmeister"; + group = "steamos"; + extraGroups = [ + "networkmanager" + "users" + "wheel" + "input" + "video" + "audio" + "render" + "gamepad" + ]; + packages = with pkgs; [ + tailscale + ]; + }; + + groups = { + steamos.gid = 1000; + gamepad = { }; + render = { }; + }; + }; + + # System Programs and Packages + programs = { + firefox.enable = true; + }; + + environment.systemPackages = with pkgs; [ + # System Tools + pciutils + usbutils + lm_sensors + dmidecode + binutils + + # Virtual Display + linuxPackages.v4l2loopback + v4l-utils + + # Development Tools + nixfmt-rfc-style + git + + # Network Tools + wget + curl + + # Utilities + tree + ]; +} +# TODO: Incorporate this part later +# Immersed Video Service +# immersed-video = { +# description = "Load v4l2loopback module for Immersed"; +# wantedBy = [ "multi-user.target" ]; +# after = [ "systemd-modules-load.service" ]; +# requires = [ "systemd-modules-load.service" ]; +# serviceConfig = { +# Type = "oneshot"; +# RemainAfterExit = true; +# ExecStartPre = "${pkgs.kmod}/bin/modprobe -r v4l2loopback || true"; +# ExecStart = "${pkgs.kmod}/bin/modprobe v4l2loopback exclusive_caps=1 video_nr=0 card_label='Immersed Virtual Camera'"; +# ExecStop = "${pkgs.kmod}/bin/rmmod v4l2loopback || true"; +# }; +# }; + +``` + +Contents of hosts/steamnix/hardware-configuration.nix: +``` +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "nvme" + "xhci_pci" + "usb_storage" + "usbhid" + "sd_mod" + "sdhci_pci" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/f3cc4aae-428e-435d-b9f7-333f7dad06b2"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/580E-5E90"; + fsType = "vfat"; + options = [ + "fmask=0077" + "dmask=0077" + ]; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.enp4s0f3u1u4u3.useDHCP = lib.mkDefault true; + # networking.interfaces.wlo1.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} + +``` + +Contents of hosts/steamnix/default.nix: +``` +{ config, lib, pkgs, ... }: + +let + jovianNixosRev = "f6423d86bec22c25a576b23262495c5536b0d069"; + jovianNixos = builtins.fetchTarball { + url = "https://github.com/Jovian-Experiments/Jovian-NixOS/archive/${jovianNixosRev}.tar.gz"; + sha256 = "sha256:1frd1dfqd97idwf1rj29ab0wvyfa2nx2h3bp9hkbmfa1m802avmb"; + }; +in +{ + imports = [ + ../common + ./hardware-configuration.nix + (jovianNixos + "/modules") + ]; + + # Configure host type + hostConfigs = { + hostType = "steamdeck"; + hasGaming = true; + hasVR = true; + }; + + # Steam Deck Specific Configuration + jovian = { + hardware.has.amd.gpu = true; + devices.steamdeck = { + enable = true; + enableControllerUdevRules = true; + enableDefaultStage1Modules = true; + enablePerfControlUdevRules = true; + enableOsFanControl = true; + enableSoundSupport = true; + enableXorgRotation = true; + enableKernelPatches = true; + enableFwupdBiosUpdates = false; + autoUpdate = false; + }; + steam.enable = false; + workarounds.ignoreMissingKernelModules = true; + }; + + # Hardware and Display Configuration + hardware.video = { + displaylink.enable = true; + }; + + services = { + xserver = { + enable = true; + xkb.layout = "us"; + videoDrivers = [ "displaylink" "modesetting" ]; + + desktopManager.plasma6 = { + enable = true; + extraSessionCommands = '' + ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0; + ''; + }; + + displayManager = { + sddm = { + enable = true; + wayland = true; + }; + sessionCommands = '' + ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 2 0 + ''; + }; + }; + + pipewire = { + enable = true; + alsa.enable = true; + pulse.enable = true; + }; + }; + +``` + +Contents of hosts/common/default.nix: +``` + +``` + +Contents of system/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./boot + ./locales + ./shell + ]; +} + +``` + +Contents of system/desktop/_plasma6.nix: +``` +{ pkgs, ... }: + +{ + # Install plasma-manager as part of home packages + home.packages = [ pkgs.plasma-manager ]; + + # Enable systemd user services for plasma-manager (optional) + systemd.user.services.plasma-manager = { + description = "Plasma Manager Service"; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = "${pkgs.plasma-manager}/bin/plasma-manager apply"; + Restart = "always"; # Ensure the service restarts if it crashes + }; + wantedBy = [ "default.target" ]; # Start the service when the user session starts + }; + + # Example of setting some KDE preferences declaratively + programs.plasma-manager.enable = true; + + # Example of setting some specific preferences + programs.plasma-manager.settings = { + # # Set wallpaper + # "plasmashell-desktop" = { + # wallpaper = "/path/to/your/wallpaper.jpg"; + # }; + + # Set panel visibility + "plasmashell-panel" = { + autohide = true; + }; + + # Set theme + "lookandfeel" = { + theme = "BreezeDark"; + }; + + # Override configuration for full declarative control + overrideConfig = true; + }; + + # Optionally, you can enable lingering to keep the service running even after logout + systemd.user.linger.enable = true; +} + +``` + +Contents of system/desktop/appimage.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "appimage" { + environment.systemPackages = with pkgs; [appimage-run]; + + # Register AppImage files as a binary type to binfmt_misc, allowing them to be invoked directly + boot.binfmt.registrations.appimage = { + wrapInterpreterInShell = false; + interpreter = "${pkgs.appimage-run}/bin/appimage-run"; + recognitionType = "magic"; + offset = 0; + mask = "\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\xff\\xff\\xff"; + magicOrExtension = "\\x7fELF....AI\\x02"; + }; +} + +``` + +Contents of system/desktop/plasma6.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + hm-config = config.hm; +in + lib.utilMods.mkModule config "plasma6" { + modules.desktop.enable = true; + modules.desktop.x11.enable = lib.mkForce true; + modules.desktop.wayland.enable = lib.mkForce true; + + # Enable the KDE's SDDM. + services.displayManager.sddm = { + enable = true; + autoNumlock = true; + enableHidpi = true; + wayland.enable = true; + }; + + # Enable Desktop Environment + services.desktopManager.plasma6 = { + enable = true; + enableQt5Integration = true; + }; + + environment.plasma6.excludePackages = with pkgs.kdePackages; [elisa]; + + # Enable KDE partition manager + programs.partition-manager.enable = true; + # Enable KDEConnect + programs.kdeconnect.enable = true; + + environment.systemPackages = with pkgs; + [ + # Apps + krename + qalculate-qt + kdiskmark + + # Libraries/Utilities + clinfo # for kinfocenter for OpenCL page + glxinfo # for kinfocenter for OpenGL EGL and GLX page + vulkan-tools # for kinfocenter for Vulkan page + wayland-utils # for kinfocenter for Wayland page + ffmpegthumbnailer # for video thumbnails + linuxquota # for plasma-disks + gnuplot # for krunner to display graphs + ] + ++ (with kdePackages; [ + # Apps + ktorrent + kfind + filelight + skanpage # Scanner + print-manager + plasma-welcome # Welcome screen + plasma-vault + plasma-disks + + # Libraries/Utilities + kdegraphics-thumbnailers + ffmpegthumbs + qtimageformats + packagekit-qt + sddm-kcm # Add KCM for sddm + ]); + + hm = { + xdg.portal = { + enable = true; + configPackages = with pkgs; lib.mkDefault [kdePackages.xdg-desktop-portal-kde]; + extraPortals = with pkgs; [xdg-desktop-portal-gtk]; + }; + + # Enable native messaging host for Firefox/Firefox forks + programs.firefox.nativeMessagingHosts = with pkgs; [kdePackages.plasma-browser-integration]; + + # Makes Plasma Browser Integration work properly for Vivaldi + xdg.configFile."vivaldi/NativeMessagingHosts/org.kde.plasma.browser_integration.json" = lib.mkIf hm-config.programs.vivaldi.enable {source = "${pkgs.kdePackages.plasma-browser-integration}/etc/chromium/native-messaging-hosts/org.kde.plasma.browser_integration.json";}; + + services.kdeconnect.enable = true; + + xdg.mimeApps = { + defaultApplications."x-scheme-handler/tel" = ["org.kde.kdeconnect.handler.desktop"]; + associations.added."x-scheme-handler/tel" = ["org.kde.kdeconnect.handler.desktop"]; + }; + }; + } + +``` + +Contents of system/desktop/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./appimage.nix + ./plasma6.nix + ]; +} + +``` + +Contents of system/boot/systemd-boot.nix: +``` +{ config, lib, ... }: + +lib.utilMods.mkModule config "systemd-boot" { + boot.loader = { + systemd-boot = { + enable = true; + memtest86.enable = true; + configurationLimit = 10; + }; + efi.canTouchEfiVariables = true; + }; +} + +``` + +Contents of system/boot/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./quietboot.nix + ./systemd-boot.nix + ]; +} + +``` + +Contents of system/boot/quietboot.nix: +``` +{ config, lib, ... }: + +lib.utilMods.mkModule config "quietboot" { + boot = { + plymouth.enable = true; + consoleLogLevel = 0; + loader.timeout = 0; + initrd.verbose = false; + kernelParams = [ "quiet" ]; + }; + + console = { + earlySetup = true; + useXkbConfig = false; + }; +} + +``` + +Contents of system/shell/zsh.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) utilMods mkIf; + hm-config = config.hm; +in + utilMods.mkModule config "zsh" { + # Forcibly Disable .zshenv + home-manager.sharedModules = [{home.file.".zshenv".enable = false;}]; + programs.zsh.enable = true; + # Source zshenv without ~/.zshenv + environment.etc."zshenv".text = ''export ZDOTDIR="$HOME"/.config/zsh''; + # Make zsh-completions work + environment.pathsToLink = ["/share/zsh"]; + + # Most of the configuration is done in Home-Manager + # Enable accompanying modules + hm.modules.atuin.enable = true; + hm.modules.oh-my-posh.enable = true; + + # The shell itself + hm.programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestion = { + enable = true; + #highlight = "underline"; + }; + syntaxHighlighting.enable = true; + dotDir = ".config/zsh"; + defaultKeymap = "viins"; + autocd = true; + history.path = "${hm-config.xdg.configHome}/zsh/.zsh_history"; + localVariables = { + # Make ZSH notifications expire, in miliseconds + AUTO_NOTIFY_EXPIRE_TIME = 5000; + # Make zsh-vi-mode be sourced + ZVM_INIT_MODE = "sourcing"; + # Disable zsh-vi-mode's custom cursors + ZVM_CURSOR_STYLE_ENABLED = false; + # Prompt message for auto correct + SPROMPT = "Correct $fg[red]%R$reset_color to $fg[green]%r$reset_color? [ny] "; + # Add more strategies to zsh-autosuggestions + ZSH_AUTOSUGGEST_STRATEGY = ["completion"]; + }; + initExtraFirst = '' + # If not running interactively, don't do anything + [[ $- != *i* ]] && return + ''; + + initExtra = '' + # Append extra variables + AUTO_NOTIFY_IGNORE+=("atuin" "yadm" "emacs" "nix-shell" "nix") + + setopt beep CORRECT # Enable terminal bell and autocorrect + autoload -U colors && colors # Enable colors + + ### Pyenv command + if command -v pyenv 1>/dev/null 2>&1; then + eval "$(pyenv init -)" + fi + + # set descriptions format to enable group support + zstyle ':completion:*:descriptions' format '[%d]' + + # set list-colors to enable filename colorizing + zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS} + + # disable sorting when completing any command + zstyle ':completion:complete:*:options' sort false + + # switch group using `,` and `.` + zstyle ':fzf-tab:*' switch-group ',' '.' + + # trigger continuous trigger with space key + zstyle ':fzf-tab:*' continuous-trigger 'space' + + # bind tab key to accept event + zstyle ':fzf-tab:*' fzf-bindings 'tab:accept' + + # accept and run suggestion with enter key + zstyle ':fzf-tab:*' accept-line enter + + ${ + if hm-config.programs.tmux.enable + then '' + # Enable fzf-tab integration with tmux + zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup + zstyle ':fzf-tab:*' popup-min-size 100 50 + '' + else "" + } + ''; + + shellAliases = { + # ZSH globbing interferes with flake notation for all nix commands + nix = "noglob nix"; + nom = "noglob nom"; + nixos-remote = "noglob nixos-remote"; + nixos-rebuild = "noglob sudo nixos-rebuild"; + nh = "noglob nh"; + + # Append HISTFILE before running autin import to make it work properly + atuin-import = + mkIf hm-config.programs.atuin.enable + "export HISTFILE && atuin import auto && unset HISTFILE"; + }; + antidote = { + enable = true; + useFriendlyNames = true; + plugins = [ + #Docs https://github.com/jeffreytse/zsh-vi-mode#-usage + "jeffreytse/zsh-vi-mode" + + # Fish-like Plugins + "mattmc3/zfunctions" + "Aloxaf/fzf-tab" + "Freed-Wu/fzf-tab-source" + "MichaelAquilina/zsh-auto-notify" + + # Sudo escape + "ohmyzsh/ohmyzsh path:lib" + "ohmyzsh/ohmyzsh path:plugins/sudo" + + # Tmux integration + (mkIf hm-config.programs.tmux.enable + "ohmyzsh/ohmyzsh path:plugins/tmux") + + # Nix stuff + "chisui/zsh-nix-shell" + + # Make ZLE use system clipboard + "kutsan/zsh-system-clipboard" + ]; + }; + }; + } + +``` + +Contents of system/shell/pass.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "password-store" { + programs.password-store = { + enable = true; + settings.PASSWORD_STORE_DIR = lib.mkDefault (throw "programs.password-store.settings.PASSWORD_STORE_DIR is not set"); + }; + + programs.password-store.package = pkgs.pass-wayland.withExtensions (p: with p; [pass-otp pass-audit pass-import pass-update pass-file pass-genphrase pass-checkup pass-tomb]); +} + +``` + +Contents of system/shell/tmux.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.programs.tmux; +in + lib.utilMods.mkModule config "tmux" { + # Fixes issue where cava can't run under tmux + home.shellAliases = lib.mkIf config.modules.cava.enable {cava = "TERM=xterm-256color cava";}; + + programs.fzf.tmux.enableShellIntegration = true; + + programs.tmux = { + enable = true; + aggressiveResize = true; + customPaneNavigationAndResize = true; + baseIndex = 1; + historyLimit = 5000; + keyMode = "vi"; + mouse = true; + #escapeTime = 0; + shortcut = "a"; + terminal = "tmux-256color"; + resizeAmount = 15; + tmuxp.enable = true; + #newSession = true; + #secureSocket = false; + extraConfig = '' + # -- more settings --------------------------------------------------------------- + set -s set-clipboard on + set -g set-titles on + set -g set-titles-string "#S / #W / #(pwd)" + set -g allow-passthrough on + set -ga update-environment TERM + set -ga update-environment TERM_PROGRAM + + set-option -g status-right-length 100 + + # Enable sixel support + set -as terminal-features 'contour:sixel' + + # Enable full RGB support + set -as terminal-features ",*-256color:RGB" + + # Pane numbers, line messages duration and status line updates + set -g display-panes-time 800 + set -g display-time 2000 + set -g status-interval 5 + + # Monitor for terminal activity changes, and manage how the alerts are displayed + set -g monitor-activity on + set -g visual-activity both + + # update files on focus + set -g focus-events on + + setw -g automatic-rename on + # Renumber windows + set -g renumber-windows on + + # Change status bar position + set -g status-position bottom + # ------------------------------------------------------------------------------------- + + + # -- keybindings ----------------------------------------------------------------- + # reload config file (change file location to your the tmux.conf you want to use) + unbind R + bind -N "Reload configuration" r source-file ${config.xdg.configHome}/tmux/tmux.conf \; display "Reloaded!" + + unbind C-p + unbind C-n + + # Setup clipboard binding keys + unbind p + bind -N "Paste the most recent paste buffer" p paste-buffer + bind -N "Go back to previous window" P previous-window + + # Tmux-copycat functionality + # https://github.com/tmux-plugins/tmux-copycat/issues/148#issuecomment-997929971 + bind -N "Copy selection" -T copy-mode-vi y send -X copy-selection-no-clear + bind -N "Search backwards" / copy-mode \; send ? + # Somewhat tmux-copycat select url functionality (requires 3.1+) + bind -N "Select URL" C-u copy-mode \; send -X search-backward "(https?://|git@|git://|ssh://|ftp://|file:///)[[:alnum:]?=%/_.:,;~@!#$&()*+-]*" + + # Navigate panes using Alt-arrow without prefix + bind -N "Switch pane, left" -n M-Left select-pane -L + bind -N "Switch pane, right" -n M-Right select-pane -R + bind -N "Switch pane, up" -n M-Up select-pane -U + bind -N "Switch pane, down" -n M-Down select-pane -D + + # Join pane bindings + bind -N "Join panes horizitonally" = choose-window 'join-pane -h -s "%%"' + bind -N "Join panes vertically" + choose-window 'join-pane -s "%%"' + + # Split pane bindings + unbind '"' + unbind % + unbind n + unbind p + bind -N "Split panes horizontally" \\ split-window -h -c "#{pane_current_path}" + bind -N "Split panes horizontally, full window length" | split-window -fh -c "#{pane_current_path}" + bind -N "Split panes vertically" - split-window -v -c "#{pane_current_path}" + bind -N "Split panes vertically, full window length" _ split-window -fv -c "#{pane_current_path}" + + # Manage Session/Window + bind -N "Switch to next window" > next-window + bind -N "Switch to previous window" < previous-window + bind -N "Create new window" c new-window -c "#{pane_current_path}" + bind -N "Create new session" C-c new-session + bind -N "Toggle between windows" Space last-window + bind -N "Toggle between current and previous session" C-Space switch-client -l + bind -N "Jump to marked session" \` switch-client -t'{marked}' + unbind & + ${ + if cfg.disableConfirmationPrompt + then '' + bind -N "Kill the active pane" x kill-pane + bind -N "Kill the current window" X kill-window + bind -N "Kill the current session" C-x kill-session + '' + else '' + bind -N "Kill the current window" X confirm-before -p "kill-window #W? (y/n)" kill-window + bind -N "Kill the current session" C-x confirm-before -p "kill-session #W? (y/n)" kill-session + '' + } + + #Example + #bind -N "Example note" h split-window -h "vim ~/scratch/notes.md" + # ------------------------------------------------------------------------------------- + ''; + plugins = with pkgs.tmuxPlugins; [ + sensible + { + plugin = yank; + extraConfig = '' + # Enable Mouse support for tmux-yank + set -g @yank_with_mouse on + ''; + } + open + fuzzback + extrakto + (lib.mkIf config.programs.fzf.enable tmux-fzf) + { + plugin = dracula; + extraConfig = '' + # Theme settings + # available plugins: battery, cpu-usage, git, gpu-usage, ram-usage, tmux-ram-usage, network, network-bandwidth, network-ping, attached-clients, network-vpn, weather, time, spotify-tui, kubernetes-context, synchronize-panes + set -g @dracula-plugins "battery cpu-usage ram-usage time" + + # Show powerline symbols + set -g @dracula-show-powerline true + + # Enable window flags + set -g @dracula-show-flags true + + # Switch left icon, can accept `session`, `smiley`, `window`, or any character. + set -g @dracula-show-left-icon smiley + + # Hide empty plugins + set -g @dracula-show-empty-plugins false + + # Theme color settings + # available colors: white, gray, dark_gray, light_purple, dark_purple, cyan, green, orange, red, pink, yellow + # set -g @dracula-[plugin-name]-colors "[background] [foreground]" + set -g @dracula-gpu-usage-colors "red white" + ''; + } + ]; + }; + } + +``` + +Contents of system/shell/shell-utils.nix: +``` +{ + config, + osConfig, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "shell-utils" { + home.packages = with pkgs; + [ + # Fancy utilities + timer # Cooler timer in terminal + tldr # better man pages + entr # run commands when files change! + procs # Better ps + ventoy-full # bootable USB solution + dust # Better du and df + libnotify + ] + ++ lib.optionals (lib.conds.isWayland osConfig) [wl-clipboard wl-clipboard-x11] + ++ lib.optionals ((lib.conds.isX11 osConfig) && (!lib.conds.isWayland osConfig)) [ + xclip + xsel + xdotool + xorg.xwininfo + xorg.xprop + ]; + + # Custom colors for ls, grep and more + programs.dircolors.enable = true; + + # smart cd command, inspired by z and autojump + programs.zoxide.enable = true; + + # Shell extension to load and unload environment variables depending on the current directory. + programs.direnv = { + enable = true; + nix-direnv.enable = true; + #config = {}; + stdlib = ''export DIRENV_ACTIVE=1''; + }; + + # Much better ls replacement + programs.eza = { + enable = true; + git = true; + icons = "auto"; + extraOptions = ["--color=always" "--group-directories-first" "--classify"]; + }; + + # Fancy 'find' replacement + programs.fd = { + enable = true; + hidden = true; + ignores = [".git/" "*.bak"]; + }; + + # Fuzzy finder + programs.fzf = { + enable = true; + # Alt-C command options + changeDirWidgetOptions = ["--preview 'eza --tree --color=always {} | head -200'"]; + # Ctrl-T command options + fileWidgetOptions = ["--bind 'ctrl-/:change-preview-window(down|hidden|)'"]; + # Ctrl-R command options + historyWidgetOptions = ["--sort" "--exact"]; + }; +} + +``` + +Contents of system/shell/atuin.nix: +``` +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "atuin" { + # The much better shell history database + programs.atuin.enable = true; + + programs.atuin.settings = { + auto_sync = true; + sync_frequency = "10m"; + search_mode = "fuzzy"; + inline_height = 16; + keymap_mode = "vim-insert"; + keymap_cursor = { + emacs = "blink-block"; + vim_insert = "blink-bar"; + vim_normal = "steady-block"; + }; + show_preview = true; + enter_accept = true; + history_filter = [ + "^gpg --key-edit" + "^gpg --list-secret-keys" + "^gpg --list-keys" + "^gpg --recipient" + "^gpg --card-edit" + "^git-crypt add-gpg-user" + "^echo" + "-----BEGIN PGP PRIVATE KEY BLOCK-----" + "^rm -rf" + "^pass" + ]; + sync.records = true; + }; +} + +``` + +Contents of system/shell/aliases.nix: +``` +{ config, lib, pkgs, ... }: + +{ + # System management + ll = "ls -la"; + update = "sudo nixos-rebuild switch"; + + # Home manager + hm = "home-manager"; + hms = "home-manager switch"; + + # Tmux + ta = "tmux attach -t"; + tl = "tmux list-sessions"; + tn = "tmux new-session -s"; + "tmux-help" = "bat ${config.xdg.configHome}/tmux/tmux-man.md --plain"; + + # Tmux natural language commands + "save-session" = "tmux command-prompt -p 'Command:' 'run-shell \"${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/save.sh\"'"; + "restore-session" = "tmux command-prompt -p 'Command:' 'run-shell \"${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/restore.sh\"'"; + "yank-text" = "tmux command-prompt -p 'Command:' 'run-shell \"tmux show-buffer | ${pkgs.xclip}/bin/xclip -selection clipboard\"'"; +} + +``` + +Contents of system/shell/bat.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "bat" { + # Fancy 'cat' replacement + programs.bat = { + enable = true; + + config.map-syntax = [".ignore:Git Ignore" "*.conf:INI"]; + + extraPackages = with pkgs.bat-extras; [ + batdiff + batgrep + batman + batpipe + prettybat + ]; + }; + + programs.fzf.fileWidgetOptions = lib.mkIf config.programs.fzf.enable (lib.mkBefore ["--preview '${pkgs.bat}/bin/bat -n --color=always {}'"]); +} + +``` + +Contents of system/shell/cava.nix: +``` +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "cava" { + # CLI audio visualizer + programs.cava.enable = true; + + programs.cava.settings = { + # Enable alacritty syncronized updates, removes flickering in alacritty + output.alacritty_sync = 1; + + general = { + mode = "normal"; + framerate = 60; + sensitivity = 100; + bars = 0; + bar_width = 1; + bar_spacing = 1; + }; + + smoothing = { + # Enable the fancy Monstercat smoothing + monstercat = 1; + # Wave mode + waves = 0; + # Gravity percentage for "drop off" + gravity = 100; + # Adjusts the integral and gravity filters to keep the signal smooth + noise_reduction = 77; + }; + + # Equalizer + eq = { + "1" = 1; + "2" = 1; + "3" = 1; + "4" = 1; + "5" = 1; + }; + }; +} + +``` + +Contents of system/shell/default.nix: +``` +{ config, lib, pkgs, ... }: + +let + sharedAliases = { + # System management + ll = "ls -la"; + update = "sudo nixos-rebuild switch"; + + # Home manager + hm = "home-manager"; + hms = "home-manager switch"; + + # Tmux + ta = "tmux attach -t"; + tl = "tmux list-sessions"; + tn = "tmux new-session -s"; + "tmux-help" = "bat ${config.xdg.configHome}/tmux/tmux-man.md --plain"; + + # Tmux natural language commands + "save-session" = "tmux command-prompt -p 'Command:' 'run-shell \"${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/save.sh\"'"; + "restore-session" = "tmux command-prompt -p 'Command:' 'run-shell \"${pkgs.tmuxPlugins.resurrect}/share/tmux-plugins/resurrect/scripts/restore.sh\"'"; + "yank-text" = "tmux command-prompt -p 'Command:' 'run-shell \"tmux show-buffer | ${pkgs.xclip}/bin/xclip -selection clipboard\"'"; + }; +in +{ + imports = [ + ./bash.nix + ./zsh.nix + ]; + + # Export the shared aliases for importing in other modules + _module.args.sharedAliases = sharedAliases; + + # Shared shell options + home.sessionVariables = { + EDITOR = "vim"; + SHELL = "${pkgs.zsh}/bin/zsh"; + }; + + # Common shell utilities + home.packages = with pkgs; [ + # System Monitoring and Process Management + htop + btop + + # Search and Navigation Tools + ripgrep + fd + fzf + tree + + # File Management and Manipulation + jq + bat + xclip + unzip + p7zip + file + + # System Information and Documentation + neofetch + tldr + ]; + + programs.fzf = { + enable = true; + enableZshIntegration = true; + defaultCommand = "rg --files --hidden --follow"; + defaultOptions = [ + "--height 40%" + "--layout=reverse" + "--border" + ]; + }; + + programs.htop = { + enable = true; + settings = { + color_scheme = 6; + cpu_count_from_one = 0; + delay = 15; + highlight_base_name = 1; + highlight_threads = 1; + show_program_path = 0; + tree_view = 1; + }; + }; +} + +``` + +Contents of system/shell/bash.nix: +``` +{ config, lib, pkgs, sharedAliases, ... }: + +{ + programs.bash = { + enable = true; + shellAliases = sharedAliases; + + initExtra = '' + # Add nix profile to PATH + export PATH=$HOME/.nix-profile/bin:$PATH + ''; + }; +} + +``` + +Contents of system/locales/us-english.nix: +``` +{ + config, + lib, + ... +}: +# English (US) display language, US English locale. +lib.utilMods.mkModule config "us-english" { + i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; + console.keyMap = lib.mkDefault "us"; + services.xserver.xkb = { + layout = lib.mkDefault "us"; + variant = lib.mkDefault ""; + }; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; +} + +``` + +Contents of system/hardware/bluetooth.nix: +``` +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "bluetooth" { + hardware.bluetooth.enable = true; + + # Fix controller compatibility + hardware.bluetooth.input.General = { + ClassicBondedOnly = false; + UserspaceHID = false; + }; +} + +``` + +Contents of system/hardware/rgb.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "openrgb" { + services.hardware.openrgb.enable = true; + services.hardware.openrgb.package = pkgs.openrgb-with-all-plugins; +} + +``` + +Contents of system/hardware/qmk.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "qmk" { + hardware.keyboard.qmk.enable = true; + + environment.systemPackages = with pkgs; [via qmk]; +} + +``` + +Contents of system/hardware/hardware-acceleration.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "hardware-accel" { + # Make sure to include this so hardware acceloration actually works + environment.sessionVariables.LD_LIBRARY_PATH = lib.mkBefore ["/run/opengl-driver/lib"]; + environment.systemPackages = with pkgs; [ + libva-utils + clinfo + glxinfo + vulkan-tools + vulkan-loader + ]; + + # Enable OpenGL + hardware.graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [libva-utils libvdpau-va-gl vulkan-validation-layers vulkan-loader]; + extraPackages32 = with pkgs; [libva-utils libvdpau-va-gl vulkan-validation-layers vulkan-loader]; + }; +} + +``` + +Contents of system/services/tailscale.nix: +``` +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "tailscale" { + services.tailscale = { + enable = true; + useRoutingFeatures = lib.mkDefault "client"; + }; + + networking.firewall = { + checkReversePath = "loose"; + allowedUDPPorts = [41641]; # Facilitate firewall punching + }; +} + +``` + +Contents of system/services/flatpak.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "flatpak" { + # Enable Flatpak + services.flatpak.enable = true; + + # Create folder where all fonts are linked to /run/current-system/sw/share/X11/fonts + fonts.fontDir.enable = true; + + # Automatically configure it + /* + systemd.services.configure-flathub-repo = { + wantedBy = ["multi-user.target"]; + path = [pkgs.flatpak]; + script = '' + flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + ''; + }; + */ + + environment.etc = { + "flatpak/remotes.d/flathub.flatpakrepo".source = pkgs.fetchurl { + url = "https://dl.flathub.org/repo/flathub.flatpakrepo"; + # Let this run once and you will get the hash as an error. + hash = "sha256-M3HdJQ5h2eFjNjAHP+/aFTzUQm9y9K+gwzc64uj+oDo="; + }; + }; +} + +``` + +Contents of system/services/syncthing.nix: +``` +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "syncthing" { + services.syncthing = { + user = lib.mkForce username; + enable = true; + dataDir = "/home/${username}/Sync"; + group = "users"; + configDir = "/home/${username}/.config/syncthing"; + openDefaultPorts = true; + }; + + environment.systemPackages = with pkgs; lib.mkIf (lib.conds.runsDesktop config) [syncthingtray-minimal]; +} + +``` + +Contents of system/services/sunshine.nix: +``` +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "sunshine-server" { + services.sunshine = { + enable = true; + autoStart = true; + capSysAdmin = true; + /* + settings = { + sunshine_name = "${config.networking.hostName}"; + }; + */ + openFirewall = true; + }; +} + +``` + +Contents of system/services/printing.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + printers = with pkgs; [hplipWithPlugin cnijfilter2]; +in + lib.utilMods.mkModule config "printing" { + # Address CUPS vulnerability CVE-2024-47076 + systemd.services.cups-browsed.enable = false; + + # Printer Setup + services.printing = { + enable = true; + drivers = printers; + }; + + # Scanner Setup + hardware.sane = { + enable = true; + extraBackends = with pkgs; [sane-airscan] ++ printers; + }; + + # Install installation + environment.systemPackages = printers; + } + +``` + +Contents of lib/mkHost.nix: +``` +{ self, inputs, lib }: +let + inherit (lib) mkOption types; +in { + mkHost = { hostname, username, system ? "x86_64-linux", profiles ? [] }: + let + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + in + inputs.nixpkgs.lib.nixosSystem { + inherit system; + + specialArgs = { + inherit inputs self hostname username; + }; + + modules = [ + # Include host-specific configuration + ../hosts/${hostname}/configuration.nix + + # Include home-manager as a module + inputs.home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = { + inherit username hostname; + }; + users.${username} = { + imports = [ + ../users/${username}/home.nix + ] ++ (map (profile: ../profiles/${profile}) profiles); + }; + }; + } + + # Basic system configuration + { + networking.hostName = hostname; + system.stateVersion = "24.05"; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + } + ]; + }; +} + +``` + +Contents of lib/secrets.nix: +``` +{ lib }: +let + internals.agePath = ../secrets; +in { + mkSecretFile = { user, source, destination ? null, owner ? null, group ? null }: + lib.filterAttrs (n: v: v != null) { + file = lib.path.append (internals.agePath + "/${user}") source; + path = destination; + inherit owner group; + }; + + mkSecretIdentities = identity: + lib.lists.forEach identity (x: + lib.path.append (internals.agePath + "/identities") x); +} + +``` + +Contents of lib/conds.nix: +``` +{ lib }: +{ + defaultStateVersion = "24.05"; + runsDesktop = config: config.modules.desktop.enable; + isWayland = config: config.modules.desktop.wayland.enable; + isX11 = config: config.modules.desktop.x11.enable; +} + +``` + +Contents of lib/utils.nix: +``` +{ lib }: +let + # Helper functions + mkEnableAttrs = value: elems: builtins.listToAttrs (map + (name: { + inherit name; + value.enable = value; + }) + elems); +in +{ + # Option helpers + mkOpt = type: default: lib.mkOption { inherit type default; }; + mkBoolOpt = default: lib.mkOption { type = lib.types.bool; inherit default; }; + + # Module management + mkModule = config: name: module: + lib.mkIf config.modules.${name}.enable module; + + enable = elems: mkEnableAttrs true elems; + disable = elems: mkEnableAttrs false elems; + enableIf = cond: elems: if cond then (mkEnableAttrs true elems) else (mkEnableAttrs false elems); + + # Import helpers + concatImports = { paths ? [ ], include ? [ ], exclude ? [ ] }: + let + isExcluded = path: builtins.elem path exclude; + validPath = path: lib.pathExists path && !isExcluded path; + in + lib.flatten (map + (path: + if validPath path + then path + else [ ] + ) + (paths ++ include)); +} + +``` + +Contents of lib/default.nix: +``` +{ self, inputs, lib }: +let + # Helper functions for internal use + internals = { + sys = import inputs.systems; + # Add standard lib function sets + inherit (lib) types mkOption; + }; + + # Define pkgsFor before using it + pkgsFor = lib.genAttrs internals.sys (system: import inputs.nixpkgs { + inherit system; + overlays = builtins.attrValues self.overlays; + config.allowUnfree = true; + }); +in +{ + # Re-export all our functions + inherit (import ./mkHost.nix { inherit self inputs lib; }) mkHost; + inherit (import ./mkHome.nix { inherit self inputs lib; }) mkHome; + inherit (import ./utils.nix { inherit lib; }) + mkOpt + mkBoolOpt + enable + disable + enableIf + mkModule; + inherit (import ./conds.nix { inherit lib; }) + defaultStateVersion + runsDesktop + isWayland + isX11; + inherit (import ./secrets.nix { inherit lib; }) + mkSecretFile + mkSecretIdentities; + + # System-wide utilities + inherit pkgsFor; + forEachSystem = fn: lib.genAttrs internals.sys (system: fn pkgsFor.${system}); + + # Add mkModule helper function + utilMods = { + mkModule = config: name: module: + lib.mkIf config.modules.${name}.enable module; + + mkEnabledModule = config: name: module: { + options.modules.${name}.enable = lib.mkEnableOption "Enable ${name} configurations"; + config = lib.mkIf config.modules.${name}.enable module; + }; + }; +} + +``` + +Contents of lib/mkHome.nix: +``` +{ self, inputs, lib }: +let + inherit (lib) mkOption types; +in { + mkHome = { username, hostname, profiles ? [] }: + let + system = "x86_64-linux"; # You can make this configurable if needed + pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + in + inputs.home-manager.lib.homeManagerConfiguration { + inherit pkgs; + + extraSpecialArgs = { + inherit username hostname; + }; + + modules = [ + # Base home-manager configuration + ../users/${username}/home.nix + + # Basic home configuration + { + home = { + inherit username; + homeDirectory = "/home/${username}"; + stateVersion = "24.05"; + }; + } + ] ++ (map (profile: ../profiles/${profile}) profiles); + }; +} + +``` + +Contents of users/jeirmeister/system.nix: +``` +{ + config, + lib, + pkgs, + username, + inputs, + ... +}: let + agenixHashedPasswordFile = lib.optionalString (lib.hasAttr "agenix" inputs) config.age.secrets."${username}-password".path; +in { + variables.user = { + fullName = "Nova Leary"; + emailAddress = "coder.nova99@mailbox.org"; + }; + variables.userIdentityPaths = lib.secrets.mkSecretIdentities ["age-yubikey-identity-a38cb00a-usba.txt"]; + + users.users.${username} = { + shell = pkgs.zsh; + extraGroups = [ + "networkmanager" + "wheel" + "video" + "audio" + "libvirtd" + "scanner" + "i2c" + "git" + "gamemode" + ]; + hashedPasswordFile = agenixHashedPasswordFile; + }; + + time.timeZone = lib.mkForce "America/Chicago"; + + # User Secrets + age.secrets."${username}-password" = lib.secrets.mkSecretFile { + user = username; + source = "passwd.age"; + }; + + # Make CAPS LOCK become CTRL key for Emacs + services.xserver.xkb.options = "terminate:ctrl_alt_bksp,caps:ctrl_modifier"; + + programs.localsend.enable = true; + + # Modules for system live under ../../modules/system + modules = lib.utils.enable [ + # Terminal + "zsh" + + # Hardware + "yubikey" + + # Services + "syncthing" + ]; + + stylix = { + enable = true; + polarity = "dark"; + base16Scheme = lib.mkForce "${pkgs.base16-schemes}/share/themes/dracula.yaml"; + image = "${inputs.wallpapers}/purple-mountains-ai.png"; + override = { + scheme = "BetterDracula"; + base00 = "282a36"; + base01 = "363447"; + base02 = "44475a"; + base03 = "6272a4"; + base04 = "9ea8c7"; + base05 = "f8f8f2"; + base06 = "f0f1f4"; + base07 = "ffffff"; + base08 = "ff5555"; + base09 = "ffb86c"; + base0A = "f1fa8c"; + base0B = "50fa7b"; + base0C = "8be9fd"; + base0D = "80bfff"; + base0E = "ff79c6"; + base0F = "bd93f9"; + }; + cursor = { + package = pkgs.capitaine-cursors; + name = "capitaine-cursors-white"; + size = 24; + }; + fonts = let + sansSerif = { + package = pkgs.nerdfonts; + name = "NotoSans Nerd Font"; + }; + serif = sansSerif; + monospace = { + package = pkgs.nerdfonts; + name = "0xProto Nerd Font Mono"; + }; + emoji = { + package = pkgs.noto-fonts-emoji; + name = "Noto Color Emoji"; + }; + sizes = { + applications = 10; + desktop = 10; + popups = 10; + terminal = 11; + }; + in {inherit sansSerif serif monospace emoji sizes;}; + opacity = { + applications = 1.0; + desktop = 1.0; + popups = 1.0; + terminal = 1.0; + }; + }; + + # Modules for users live under ../../modules/home + hm.variables = { + defaultTerminal = "kitty"; + defaultBrowser = "floorp"; + defaultTextEditor = "doom-emacs"; + }; + + hm.home.packages = with pkgs; [openscad freecad rpi-imager blisp libreoffice-qt6-fresh keepassxc krita kdePackages.tokodon]; + + hm.stylix.targets = lib.mkForce { + # Enable 256 colors for kitty + kitty.variant256Colors = true; + # Causes some mismatched colors with Dracula-tmux theme + tmux.enable = false; + # Disable stylix's KDE module, very broken currently + kde.enable = false; + }; + + hm.age.secrets."borg_token" = lib.secrets.mkSecretFile { + user = username; + source = "borg.age"; + destination = "${config.hm.xdg.configHome}/borg/keys/srv_dev_disk_by_uuid_5aaed6a3_d2c7_4623_b121_5ebb8d37d930_Backups"; + }; + hm.modules = lib.utils.enable [ + # Core + "git" + "doom-emacs" + "password-store" + + # Terminal Utils + "shell-utils" + "nix" + "cava" + "tmux" + "bat" + "btop" + "fastfetch" + "topgrade" + + # Development Environment + "latex" + "lua" + "markdown" + "python" + "rust" + + # Applications + #"vivaldi" + "jellyfin-player" + "borg" + "discord" + ]; +} + +``` + +Contents of users/jeirmeister/monsterbabe.nix: +``` +{ + config, + lib, + pkgs, + username, + osConfig, + ... +}: { + xdg.configFile = { + "OpenRGB/plugins/settings/effect-profiles/default".source = lib.dots.getDotsPath { + user = username; + path = "openrgb/rgb-default-effect.json"; + }; + "OpenRGB/plugins/settings/EffectSettings.json".source = lib.dots.getDotsPath { + user = username; + path = "openrgb/rgb-effect-settings.json"; + }; + }; + + programs.rio.settings.window = { + width = 1000; + height = 600; + }; +} + +``` + +Contents of users/jeirmeister/steamdeck.nix: +``` +{ + config, + lib, + pkgs, + ... +}: { + home.packages = with pkgs; [moonlight-qt]; + + programs.rio.settings.window = { + width = 1200; + height = 800; + }; +} + +``` + +Contents of users/jeirmeister/config/git.nix: +``` +_: { + programs.git = { + userName = "NovaViper"; + userEmail = "coder.nova99@mailbox.org"; + signing = { + key = "DEAB6E5298F9C516"; + signByDefault = true; + }; + }; +} + +``` + +Contents of users/jeirmeister/config/zsh.nix: +``` +{ + config, + osConfig, + lib, + pkgs, + ... +}: +with lib; { + xdg.configFile = mkMerge [ + (mkIf osConfig.modules.zsh.enable { + "zsh/.p10k.zsh" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "zsh/.p10k.zsh"; + }; + "zsh/functions" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "zsh/functions"; + }; + }) + + (mkIf config.modules.tmux.enable { + "tmuxp/session.yaml" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "tmuxp/session.yaml"; + }; + }) + ]; + + home.packages = with pkgs; [ + # Terminal Decorations + toilet # Display fancy text in terminal + dwt1-shell-color-scripts # Display cool graphics in terminal + ]; + + programs.zsh = { + initExtraFirst = lib.mkAfter '' + ${ + if config.modules.tmux.enable + then '' + # Run Tmux on startup + if [ -z "$TMUX" ]; then + ${pkgs.tmux}/bin/tmux attach >/dev/null 2>&1 || ${pkgs.tmuxp}/bin/tmuxp load ${config.xdg.configHome}/tmuxp/session.yaml >/dev/null 2>&1 + exit + fi + '' + else "" + } + ''; + initExtra = lib.mkAfter '' + # Create shell prompt + if [ $(tput cols) -ge '75' ] || [ $(tput cols) -ge '100' ]; then + ${pkgs.toilet}/bin/toilet -f pagga "FOSS AND BEAUTIFUL" --metal + ${pkgs.fastfetch}/bin/fastfetch + fi + ''; + }; +} + +``` + +Contents of users/jeirmeister/config/pass.nix: +``` +{config, ...}: { + programs.password-store.settings.PASSWORD_STORE_DIR = "${config.home.homeDirectory}/Sync/.password-store"; +} + +``` + +Contents of users/jeirmeister/config/virt-manager.nix: +``` +_: { + dconf.settings = { + "org/virt-manager/virt-manager" = { + system-tray = true; + xmleditor-enabled = true; + }; + + "org/virt-manager/virt-manager/connections" = { + autoconnect = ["qemu:///system"]; + uris = ["qemu:///system"]; + }; + + "org/virt-manager/virt-manager/stats" = { + enable-disk-poll = true; + enable-memory-poll = true; + enable-net-poll = true; + }; + + "org/virt-manager/virt-manager/console" = { + resize-guest = 1; + scaling = 2; + }; + + "org/virt-manager/virt-manager/new-vm" = { + cpu-default = "host-passthrough"; + }; + }; +} + +``` + +Contents of users/jeirmeister/config/vr.nix: +``` +{ + config, + osConfig, + lib, + ... +}: { + xdg.configFile = lib.mkIf osConfig.modules.gaming.vr.enable { + "alvr/session.json" = lib.dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "alvr/session.json"; + }; + /* + "openxr/1/active_runtime.json"= outputs.lib.mkDotsSymlink { + config = config; + user = config.home.username; + source = "alvr/active_runtime.json"; + }; + */ + }; +} + +``` + +Contents of users/jeirmeister/config/ssh.nix: +``` +{config, ...}: { + programs.ssh.matchBlocks = { + "knoxpi-*" = { + hostname = "192.168.1.101"; + identityFile = "${config.home.homeDirectory}/.ssh/id_ecdsa_sk_rk_knox"; + port = 22; + extraOptions = { + RequestTTY = "yes"; + RemoteCommand = "tmux new-session -A -s \${%n}"; + }; + }; + "knoxpi" = { + hostname = "192.168.1.101"; + identityFile = "${config.home.homeDirectory}/.ssh/id_ecdsa_sk_rk_knox"; + port = 22; + }; + "printerpi" = { + user = "exova"; + hostname = "192.168.1.81"; + port = 22; + }; + }; +} + +``` + +Contents of users/jeirmeister/config/theme.nix: +``` +{ + config, + lib, + pkgs, + inputs, + ... +}: { + theme = { + packages = with pkgs; [dracula-theme]; + name = "Dracula"; + nameSymbolic = "dracula"; + app.rio.name = config.theme.name; + iconTheme = { + package = pkgs.papirus-icon-theme.override { + color = "violet"; + }; + name = "Papirus-Dark"; + }; + }; + + programs = { + plasma = let + workspace = { + lookAndFeel = "org.kde.breezedark.desktop"; + colorScheme = "DraculaPurple"; + #splashScreen = ""; + wallpaperSlideShow = { + path = ["${inputs.wallpapers}/"]; + interval = 300; + }; + }; + in { + overrideConfig = true; + inherit workspace; + kscreenlocker.appearance.wallpaperSlideShow = workspace.wallpaperSlideShow; + }; + cava.settings.color = { + gradient = 1; + gradient_count = 8; + gradient_color_1 = "'#8BE9FD'"; + gradient_color_2 = "'#9AEDFE'"; + gradient_color_3 = "'#CAA9FA'"; + gradient_color_4 = "'#BD93F9'"; + gradient_color_5 = "'#FF92D0'"; + gradient_color_6 = "'#FF79C6'"; + gradient_color_7 = "'#FF6E67'"; + gradient_color_8 = "'#FF5555'"; + }; + }; +} + +``` + +Contents of users/jeirmeister/config/kde6/panels.nix: +``` +{ + config, + pkgs, + ... +}: { + home.packages = with pkgs; [plasma-panel-colorizer]; + + programs.plasma.panels = [ + # Windows like panel at the bottom + { + location = "bottom"; + height = 46; + floating = false; + widgets = [ + { + kickoff = { + icon = "nix-snowflake"; + sidebarPosition = "right"; + showButtonsFor = "powerAndSession"; + showActionButtonCaptions = false; + }; + } + "org.kde.plasma.marginsseparator" + { + iconTasks = { + appearance = { + showTooltips = true; + highlightWindows = true; + indicateAudioStreams = true; + fill = true; + }; + launchers = let + # Auto switch terminal application desktop file + terminal = + if builtins.hasAttr "TERMINAL" config.home.sessionVariables + then "${config.home.sessionVariables.TERMINAL}" + else "org.kde.konsole"; + in [ + "preferred://browser" + "applications:systemsettings.desktop" + "preferred://filemanager" + "applications:${terminal}.desktop" + "applications:emacsclient.desktop" + "applications:org.kde.krita.desktop" + "applications:writer.desktop" + ]; + }; + } + "org.kde.plasma.marginsseparator" + "org.kde.plasma.pager" + "org.kde.plasma.showdesktop" + ]; + } + { + location = "top"; + height = 26; + floating = true; + widgets = [ + { + applicationTitleBar = { + layout.elements = []; + windowControlButtons = { + iconSource = "breeze"; + buttonsAspectRatio = 95; + buttonsMargin = 0; + }; + windowTitle = { + source = "appName"; + hideEmptyTitle = true; + undefinedWindowTitle = ""; + margins = { + left = 5; + right = 5; + }; + }; + overrideForMaximized = { + enable = true; + elements = ["windowCloseButton" "windowMaximizeButton" "windowMinimizeButton" "windowIcon" "windowTitle"]; + source = "appName"; + }; + }; + } + "org.kde.plasma.appmenu" + "org.kde.plasma.panelspacer" + { + digitalClock = { + date = { + enable = true; + position = "besideTime"; + }; + time.showSeconds = "always"; + }; + } + "org.kde.plasma.panelspacer" + { + systemTray = { + icons.scaleToFit = true; + items = { + shown = [ + "org.kde.plasma.battery" + ]; + configs.battery.showPercentage = true; + }; + }; + } + ]; + } + ]; +} + +``` + +Contents of users/jeirmeister/config/kde6/common.nix: +``` +{ + config, + pkgs, + ... +}: { + programs.plasma = { + enable = true; + kwin = { + titlebarButtons = { + left = ["close" "maximize" "minimize"]; + right = ["keep-above-windows" "on-all-desktops"]; + }; + borderlessMaximizedWindows = true; + }; + hotkeys.commands."restart-plasmashell" = { + name = "Restart Plasmashell"; + key = "Meta+Alt+R"; + command = "${pkgs.restart-plasma}/bin/restart-plasma"; + }; + configFile = { + ksmserverrc.General.loginMode = "restoreSavedSession"; # Force KDE to launch apps when a session was manually saved + kdeglobals = let + # Auto switch terminal application desktop file + terminal = + if builtins.hasAttr "TERMINAL" config.home.sessionVariables + then "${config.home.sessionVariables.TERMINAL}" + else "org.kde.konsole"; + in { + General.TerminalApplication = "${terminal}.destop"; + General.TerminalService = "${terminal}.desktop"; + }; + kservicemenurc.Show = { + "compressfileitemaction" = true; + "extractfileitemaction" = true; + "forgetfileitemaction" = true; + "installFont" = true; + "kactivitymanagerd_fileitem_linking_plugin" = true; + "kdeconnectfileitemaction" = true; + "kio-admin" = true; + "makefileactions" = true; + "mountisoaction" = true; + "plasmavaultfileitemaction" = true; + "runInKonsole" = true; + "slideshowfileitemaction" = true; + "tagsfileitemaction" = true; + "wallpaperfileitemaction" = true; + }; + dolphinrc = { + ContentDisplay.UsePermissionsFormat = "CombinedFormat"; + VersionControl.enabledPlugins = "Git"; + General = { + "AutoExpandFolders" = true; + "FilterBar" = true; + "ShowFullPathInTitlebar" = true; + "ShowToolTips" = true; + "SortingChoice" = "CaseInsensitiveSorting"; + "UseTabForSwitchingSplitView" = true; + }; + PreviewSettings.Plugins = "appimagethumbnail,audiothumbnail,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,ffmpegthumbs"; + }; + }; + }; +} + +``` + +Contents of users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json: +``` +{ + "audio_settings": { + "amplitude": 100, + "audio_device": -1, + "avg_mode": 0, + "avg_size": 8, + "decay": 80, + "equalizer": [ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0 + ], + "filter_constant": 1.0, + "nrml_ofst": 0.03999999910593033, + "nrml_scl": 0.5, + "window_mode": 0 + }, + "brightness": 100, + "fps": 60, + "fpscapture": 60, + "hide_unsupported": false, + "prefer_random": false, + "prefered_colors": [], + "startup_profile": "default", + "temperature": 0, + "tint": 0, + "use_prefered_colors": false +} + +``` + +Contents of users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json: +``` +{ + "Effects": [ + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 100, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 0 + } + ], + "CustomName": "", + "EffectClassName": "Breathing", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 1, + "Speed": 160, + "Temperature": 0, + "Tint": 0, + "UserColors": [16715419] + }, + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 100, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 3 + } + ], + "CustomName": "", + "EffectClassName": "Visor", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 20, + "Speed": 50, + "Temperature": 0, + "Tint": 0, + "UserColors": [8323327, 8323327] + }, + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 50, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 1 + } + ], + "CustomName": "", + "CustomSettings": { + "background": 0 + }, + "EffectClassName": "MotionPoint", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 1, + "Speed": 25, + "Temperature": 0, + "Tint": 0, + "UserColors": [16715354] + } + ], + "version": 2 +} + +``` + +Contents of users/jeirmeister/dotfiles/tmuxp/session.yaml: +``` +session_name: 3-panes +windows: + - default: + layout: 63bb,132x42,0,0{83x42,0,0,0,48x42,84,0[48x21,84,0,1,48x20,84,22,2]} + panes: + - shell_command: + - + focus: true + - + - environment: + TERM: "xterm-256color" + shell_command: cava + #- cmatrix -ba -u 3 -C blue + +``` + +Contents of users/jeirmeister/dotfiles/alvr/session.json: +``` +{ + "server_version": "20.11.0", + "drivers_backup": null, + "openvr_config": { + "eye_resolution_width": 2592, + "eye_resolution_height": 2848, + "target_eye_resolution_width": 2592, + "target_eye_resolution_height": 2848, + "tracking_ref_only": false, + "enable_vive_tracker_proxy": false, + "aggressive_keyframe_resend": false, + "adapter_index": 0, + "codec": 0, + "h264_profile": 0, + "refresh_rate": 72, + "use_10bit_encoder": false, + "use_full_range_encoding": true, + "encoding_gamma": 1.0, + "enable_hdr": false, + "force_hdr_srgb_correction": false, + "clamp_hdr_extended_range": false, + "enable_pre_analysis": false, + "enable_vbaq": false, + "enable_hmqb": false, + "use_preproc": false, + "preproc_sigma": 4, + "preproc_tor": 7, + "amd_encoder_quality_preset": 0, + "rate_control_mode": 0, + "filler_data": false, + "entropy_coding": 1, + "force_sw_encoding": true, + "sw_thread_count": 11, + "controller_is_tracker": false, + "controllers_enabled": true, + "body_tracking_vive_enabled": false, + "body_tracking_has_legs": false, + "enable_foveated_encoding": true, + "foveation_center_size_x": 0.45, + "foveation_center_size_y": 0.4, + "foveation_center_shift_x": 0.4, + "foveation_center_shift_y": 0.1, + "foveation_edge_ratio_x": 4.0, + "foveation_edge_ratio_y": 5.0, + "enable_color_correction": true, + "brightness": 0.0, + "contrast": 0.0, + "saturation": 0.5, + "gamma": 1.0, + "sharpening": 0.5, + "linux_async_compute": false, + "linux_async_reprojection": false, + "nvenc_quality_preset": 5, + "nvenc_tuning_preset": 2, + "nvenc_multi_pass": 1, + "nvenc_adaptive_quantization_mode": 1, + "nvenc_low_delay_key_frame_scale": -1, + "nvenc_refresh_rate": -1, + "enable_intra_refresh": false, + "intra_refresh_period": -1, + "intra_refresh_count": -1, + "max_num_ref_frames": -1, + "gop_length": -1, + "p_frame_strategy": -1, + "nvenc_rate_control_mode": -1, + "rc_buffer_size": -1, + "rc_initial_delay": -1, + "rc_max_bitrate": -1, + "rc_average_bitrate": -1, + "nvenc_enable_weighted_prediction": false, + "capture_frame_dir": "", + "amd_bitrate_corruption_fix": false, + "use_separate_hand_trackers": true, + "_controller_profile": 1, + "_server_impl_debug": false, + "_client_impl_debug": false, + "_server_core_debug": false, + "_client_core_debug": false, + "_conncection_debug": false, + "_sockets_debug": false, + "_server_gfx_debug": false, + "_client_gfx_debug": false, + "_encoder_debug": false, + "_decoder_debug": false + }, + "client_connections": { + "3964.client": { + "display_name": "Quest 2", + "current_ip": "192.168.1.238", + "manual_ips": [], + "trusted": true, + "connection_state": "Disconnected", + "cabled": false + } + }, + "session_settings": { + "video": { + "bitrate": { + "gui_collapsed": false, + "mode": { + "ConstantMbps": 30, + "Adaptive": { + "gui_collapsed": true, + "saturation_multiplier": 0.95, + "max_bitrate_mbps": { + "enabled": false, + "content": 100 + }, + "min_bitrate_mbps": { + "enabled": false, + "content": 5 + }, + "max_network_latency_ms": { + "enabled": false, + "content": 8 + }, + "encoder_latency_limiter": { + "enabled": true, + "content": { + "max_saturation_multiplier": 0.9 + } + }, + "decoder_latency_limiter": { + "enabled": true, + "content": { + "gui_collapsed": false, + "max_decoder_latency_ms": 30, + "latency_overstep_frames": 90, + "latency_overstep_multiplier": 0.99 + } + } + }, + "variant": "ConstantMbps" + }, + "adapt_to_framerate": { + "enabled": false, + "content": { + "framerate_reset_threshold_multiplier": 2.0 + } + }, + "history_size": 256, + "image_corruption_fix": false + }, + "preferred_codec": { + "variant": "H264" + }, + "foveated_encoding": { + "enabled": true, + "content": { + "force_enable": false, + "center_size_x": 0.45, + "center_size_y": 0.4, + "center_shift_x": 0.4, + "center_shift_y": 0.1, + "edge_ratio_x": 4.0, + "edge_ratio_y": 5.0 + } + }, + "color_correction": { + "enabled": true, + "content": { + "brightness": 0.0, + "contrast": 0.0, + "saturation": 0.5, + "gamma": 1.0, + "sharpening": 0.5 + } + }, + "max_buffering_frames": 2.0, + "buffering_history_weight": 0.9, + "optimize_game_render_latency": true, + "encoder_config": { + "gui_collapsed": false, + "rate_control_mode": { + "variant": "Cbr" + }, + "filler_data": false, + "h264_profile": { + "variant": "High" + }, + "entropy_coding": { + "variant": "Cavlc" + }, + "use_10bit": false, + "use_full_range": true, + "encoding_gamma": 1.0, + "enable_hdr": false, + "force_hdr_srgb_correction": false, + "clamp_hdr_extended_range": false, + "nvenc": { + "gui_collapsed": true, + "quality_preset": { + "variant": "P5" + }, + "tuning_preset": { + "variant": "LowLatency" + }, + "multi_pass": { + "variant": "QuarterResolution" + }, + "adaptive_quantization_mode": { + "variant": "Spatial" + }, + "low_delay_key_frame_scale": -1, + "refresh_rate": -1, + "enable_intra_refresh": false, + "intra_refresh_period": -1, + "intra_refresh_count": -1, + "max_num_ref_frames": -1, + "gop_length": -1, + "p_frame_strategy": -1, + "rate_control_mode": -1, + "rc_buffer_size": -1, + "rc_initial_delay": -1, + "rc_max_bitrate": -1, + "rc_average_bitrate": -1, + "enable_weighted_prediction": false + }, + "amf": { + "gui_collapsed": true, + "quality_preset": { + "variant": "Quality" + }, + "enable_vbaq": false, + "enable_hmqb": false, + "use_preproc": false, + "preproc_sigma": 4, + "preproc_tor": 7, + "enable_pre_analysis": false + }, + "software": { + "force_software_encoding": true, + "thread_count": 11 + } + }, + "force_software_decoder": false, + "mediacodec_extra_options": { + "gui_collapsed": true, + "key": "", + "value": { + "Float": 0.0, + "Int32": 0, + "Int64": 0, + "String": "", + "variant": "Int32" + }, + "content": [ + [ + "operating-rate", + { + "Float": 0.0, + "Int32": 2147483647, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ], + [ + "priority", + { + "Float": 0.0, + "Int32": 0, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ], + [ + "vendor.qti-ext-dec-low-latency.enable", + { + "Float": 0.0, + "Int32": 1, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ] + ] + }, + "transcoding_view_resolution": { + "Scale": 1.0, + "Absolute": { + "width": 2592, + "height": { + "set": false, + "content": 1072 + } + }, + "variant": "Absolute" + }, + "emulated_headset_view_resolution": { + "Scale": 1.0, + "Absolute": { + "width": 2592, + "height": { + "set": false, + "content": 1072 + } + }, + "variant": "Absolute" + }, + "preferred_fps": 72.0, + "adapter_index": 0, + "clientside_foveation": { + "enabled": false, + "content": { + "mode": { + "Static": { + "level": { + "variant": "High" + } + }, + "Dynamic": { + "max_level": { + "variant": "High" + } + }, + "variant": "Dynamic" + }, + "vertical_offset_deg": 0.0 + } + } + }, + "audio": { + "game_audio": { + "enabled": true, + "content": { + "gui_collapsed": false, + "device": { + "set": false, + "content": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + } + }, + "mute_when_streaming": true, + "buffering": { + "gui_collapsed": false, + "average_buffering_ms": 50, + "batch_ms": 10 + } + } + }, + "microphone": { + "enabled": true, + "content": { + "gui_collapsed": false, + "devices": { + "Custom": { + "sink": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + }, + "source": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + } + }, + "variant": "Automatic" + }, + "buffering": { + "gui_collapsed": false, + "average_buffering_ms": 50, + "batch_ms": 10 + } + } + } + }, + "headset": { + "position_recentering_mode": { + "Local": { + "view_height": 1.5 + }, + "variant": "LocalFloor" + }, + "rotation_recentering_mode": { + "variant": "Yaw" + }, + "controllers": { + "enabled": true, + "content": { + "gui_collapsed": false, + "tracked": true, + "hand_skeleton": { + "enabled": true, + "content": { + "steamvr_input_2_0": true + } + }, + "multimodal_tracking": false, + "hand_tracking_interaction": { + "enabled": false, + "content": { + "only_touch": false, + "pinch_touch_distance": 0.0, + "pinch_trigger_distance": 0.25, + "curl_touch_distance": 2.0, + "curl_trigger_distance": 2.5, + "joystick_deadzone": 40.0, + "joystick_offset_horizontal": 0.0, + "joystick_offset_vertical": 0.0, + "joystick_range": 1.0, + "activation_delay": 50, + "deactivation_delay": 100, + "repeat_delay": 100 + } + }, + "steamvr_pipeline_frames": 3.0, + "haptics": { + "enabled": true, + "content": { + "gui_collapsed": true, + "intensity_multiplier": 1.0, + "amplitude_curve": 1.0, + "min_duration_s": 0.01 + } + }, + "emulation_mode": { + "Custom": { + "serial_number": "ALVR Controller", + "button_set": { + "gui_collapsed": false, + "element": "/user/hand/left/input/a/click", + "content": [] + } + }, + "variant": "Quest2Touch" + }, + "extra_openvr_props": { + "gui_collapsed": true, + "element": { + "TrackingSystemName": "", + "ModelNumber": "", + "SerialNumber": "", + "RenderModelName": "", + "WillDriftInYaw": false, + "ManufacturerName": "", + "TrackingFirmwareVersion": "", + "HardwareRevisionString": "", + "AllWirelessDongleDescriptions": "", + "ConnectedWirelessDongle": "", + "DeviceIsWireless": false, + "DeviceIsCharging": false, + "DeviceBatteryPercentage": 0.0, + "FirmwareUpdateAvailable": false, + "FirmwareManualUpdate": false, + "FirmwareManualUpdateURL": "", + "HardwareRevisionUint64": 0, + "FirmwareVersion": 0, + "FPGAVersion": 0, + "VRCVersion": 0, + "RadioVersion": 0, + "DongleVersion": 0, + "BlockServerShutdown": false, + "CanUnifyCoordinateSystemWithHmd": false, + "ContainsProximitySensor": false, + "DeviceProvidesBatteryStatus": false, + "DeviceCanPowerOff": false, + "FirmwareProgrammingTarget": "", + "DeviceClass": 0, + "HasCamera": false, + "DriverVersion": "", + "FirmwareForceUpdateRequired": false, + "ViveSystemButtonFixRequired": false, + "ParentDriver": 0, + "ResourceRoot": "", + "RegisteredDeviceType": "", + "InputProfilePath": "", + "NeverTracked": false, + "NumCameras": 0, + "CameraFrameLayout": 0, + "CameraStreamFormat": 0, + "AdditionalDeviceSettingsPath": "", + "Identifiable": false, + "BootloaderVersion": 0, + "AdditionalSystemReportData": "", + "CompositeFirmwareVersion": "", + "FirmwareRemindUpdate": false, + "PeripheralApplicationVersion": 0, + "ManufacturerSerialNumber": "", + "ComputedSerialNumber": "", + "EstimatedDeviceFirstUseTime": 0, + "ReportsTimeSinceVSync": false, + "SecondsFromVsyncToPhotons": 0.0, + "DisplayFrequency": 0.0, + "UserIpdMeters": 0.0, + "CurrentUniverseId": 0, + "PreviousUniverseId": 0, + "DisplayFirmwareVersion": 0, + "IsOnDesktop": false, + "DisplayMCType": 0, + "DisplayMCOffset": 0.0, + "DisplayMCScale": 0.0, + "EdidVendorID": 0, + "DisplayMCImageLeft": "", + "DisplayMCImageRight": "", + "DisplayGCBlackClamp": 0.0, + "EdidProductID": 0, + "DisplayGCType": 0, + "DisplayGCOffset": 0.0, + "DisplayGCScale": 0.0, + "DisplayGCPrescale": 0.0, + "DisplayGCImage": "", + "LensCenterLeftU": 0.0, + "LensCenterLeftV": 0.0, + "LensCenterRightU": 0.0, + "LensCenterRightV": 0.0, + "UserHeadToEyeDepthMeters": 0.0, + "CameraFirmwareVersion": 0, + "CameraFirmwareDescription": "", + "DisplayFPGAVersion": 0, + "DisplayBootloaderVersion": 0, + "DisplayHardwareVersion": 0, + "AudioFirmwareVersion": 0, + "CameraCompatibilityMode": 0, + "ScreenshotHorizontalFieldOfViewDegrees": 0.0, + "ScreenshotVerticalFieldOfViewDegrees": 0.0, + "DisplaySuppressed": false, + "DisplayAllowNightMode": false, + "DisplayMCImageWidth": 0, + "DisplayMCImageHeight": 0, + "DisplayMCImageNumChannels": 0, + "SecondsFromPhotonsToVblank": 0.0, + "DriverDirectModeSendsVsyncEvents": false, + "DisplayDebugMode": false, + "GraphicsAdapterLuid": 0, + "DriverProvidedChaperonePath": "", + "ExpectedTrackingReferenceCount": 0, + "ExpectedControllerCount": 0, + "NamedIconPathControllerLeftDeviceOff": "", + "NamedIconPathControllerRightDeviceOff": "", + "NamedIconPathTrackingReferenceDeviceOff": "", + "DoNotApplyPrediction": false, + "DistortionMeshResolution": 0, + "DriverIsDrawingControllers": false, + "DriverRequestsApplicationPause": false, + "DriverRequestsReducedRendering": false, + "MinimumIpdStepMeters": 0.0, + "AudioBridgeFirmwareVersion": 0, + "ImageBridgeFirmwareVersion": 0, + "ImuFactoryGyroBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryGyroScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ConfigurationIncludesLighthouse20Features": false, + "AdditionalRadioFeatures": 0, + "ExpectedControllerType": "", + "HmdTrackingStyle": 0, + "DriverProvidedChaperoneVisibility": false, + "HmdColumnCorrectionSettingPrefix": "", + "CameraSupportsCompatibilityModes": false, + "SupportsRoomViewDepthProjection": false, + "DisplaySupportsMultipleFramerates": false, + "DisplayColorMultLeft": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplayColorMultRight": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplaySupportsRuntimeFramerateChange": false, + "DisplaySupportsAnalogGain": false, + "DisplayMinAnalogGain": 0.0, + "DisplayMaxAnalogGain": 0.0, + "DashboardScale": 0.0, + "IpdUIRangeMinMeters": 0.0, + "IpdUIRangeMaxMeters": 0.0, + "HmdSupportsHDCP14LegacyCompat": false, + "HmdSupportsMicMonitoring": false, + "DriverRequestedMuraCorrectionMode": 0, + "DriverRequestedMuraFeatherInnerLeft": 0, + "DriverRequestedMuraFeatherInnerRight": 0, + "DriverRequestedMuraFeatherInnerTop": 0, + "DriverRequestedMuraFeatherInnerBottom": 0, + "DriverRequestedMuraFeatherOuterLeft": 0, + "DriverRequestedMuraFeatherOuterRight": 0, + "DriverRequestedMuraFeatherOuterTop": 0, + "DriverRequestedMuraFeatherOuterBottom": 0, + "AudioDefaultPlaybackDeviceId": "", + "AudioDefaultRecordingDeviceId": "", + "AudioDefaultPlaybackDeviceVolume": 0.0, + "AudioSupportsDualSpeakerAndJackOutput": false, + "AttachedDeviceId": "", + "SupportedButtons": 0, + "Axis0Type": 0, + "Axis1Type": 0, + "Axis2Type": 0, + "Axis3Type": 0, + "Axis4Type": 0, + "ControllerRoleHint": 0, + "FieldOfViewLeftDegrees": 0.0, + "FieldOfViewRightDegrees": 0.0, + "FieldOfViewTopDegrees": 0.0, + "FieldOfViewBottomDegrees": 0.0, + "TrackingRangeMinimumMeters": 0.0, + "TrackingRangeMaximumMeters": 0.0, + "ModeLabel": "", + "CanWirelessIdentify": false, + "Nonce": 0, + "IconPathName": "", + "NamedIconPathDeviceOff": "", + "NamedIconPathDeviceSearching": "", + "NamedIconPathDeviceSearchingAlert": "", + "NamedIconPathDeviceReady": "", + "NamedIconPathDeviceReadyAlert": "", + "NamedIconPathDeviceNotReady": "", + "NamedIconPathDeviceStandby": "", + "NamedIconPathDeviceAlertLow": "", + "NamedIconPathDeviceStandbyAlert": "", + "OverrideContainer": 0, + "UserConfigPath": "", + "InstallPath": "", + "HasDisplayComponent": false, + "HasControllerComponent": false, + "HasCameraComponent": false, + "HasDriverDirectModeComponent": false, + "HasVirtualDisplayComponent": false, + "HasSpatialAnchorsSupport": false, + "ControllerType": "", + "ControllerHandSelectionPriority": 0, + "variant": "TrackingSystemName" + }, + "content": [] + }, + "linear_velocity_cutoff": 0.05, + "angular_velocity_cutoff": 10.0, + "left_controller_position_offset": { + "gui_collapsed": true, + "content": [ + 0.0, + 0.0, + -0.11 + ] + }, + "left_controller_rotation_offset": { + "gui_collapsed": true, + "content": [ + -20.0, + 0.0, + 0.0 + ] + }, + "left_hand_tracking_position_offset": { + "gui_collapsed": true, + "content": [ + 0.04, + -0.02, + -0.13 + ] + }, + "left_hand_tracking_rotation_offset": { + "gui_collapsed": true, + "content": [ + 0.0, + -45.0, + -90.0 + ] + }, + "button_mappings": { + "set": false, + "content": { + "gui_collapsed": false, + "key": "/user/hand/left/input/a/click", + "value": { + "gui_collapsed": false, + "element": { + "destination": "/user/hand/left/input/a/click", + "mapping_type": { + "HysteresisThreshold": { + "value": 0.5, + "deviation": 0.05 + }, + "BinaryToScalar": { + "off": 0.0, + "on": 1.0 + }, + "Remap": { + "min": 0.0, + "max": 1.0 + }, + "variant": "Passthrough" + }, + "binary_conditions": { + "gui_collapsed": true, + "element": "/user/hand/left/input/trigger/touch", + "content": [] + } + }, + "content": [] + }, + "content": [] + } + }, + "button_mapping_config": { + "gui_collapsed": true, + "click_threshold": { + "value": 0.5, + "deviation": 0.05 + }, + "touch_threshold": { + "value": 0.1, + "deviation": 0.05 + }, + "force_threshold": 0.8 + } + } + }, + "emulation_mode": { + "Custom": { + "serial_number": "Unknown" + }, + "variant": "Quest2" + }, + "extra_openvr_props": { + "gui_collapsed": true, + "element": { + "TrackingSystemName": "", + "ModelNumber": "", + "SerialNumber": "", + "RenderModelName": "", + "WillDriftInYaw": false, + "ManufacturerName": "", + "TrackingFirmwareVersion": "", + "HardwareRevisionString": "", + "AllWirelessDongleDescriptions": "", + "ConnectedWirelessDongle": "", + "DeviceIsWireless": false, + "DeviceIsCharging": false, + "DeviceBatteryPercentage": 0.0, + "FirmwareUpdateAvailable": false, + "FirmwareManualUpdate": false, + "FirmwareManualUpdateURL": "", + "HardwareRevisionUint64": 0, + "FirmwareVersion": 0, + "FPGAVersion": 0, + "VRCVersion": 0, + "RadioVersion": 0, + "DongleVersion": 0, + "BlockServerShutdown": false, + "CanUnifyCoordinateSystemWithHmd": false, + "ContainsProximitySensor": false, + "DeviceProvidesBatteryStatus": false, + "DeviceCanPowerOff": false, + "FirmwareProgrammingTarget": "", + "DeviceClass": 0, + "HasCamera": false, + "DriverVersion": "", + "FirmwareForceUpdateRequired": false, + "ViveSystemButtonFixRequired": false, + "ParentDriver": 0, + "ResourceRoot": "", + "RegisteredDeviceType": "", + "InputProfilePath": "", + "NeverTracked": false, + "NumCameras": 0, + "CameraFrameLayout": 0, + "CameraStreamFormat": 0, + "AdditionalDeviceSettingsPath": "", + "Identifiable": false, + "BootloaderVersion": 0, + "AdditionalSystemReportData": "", + "CompositeFirmwareVersion": "", + "FirmwareRemindUpdate": false, + "PeripheralApplicationVersion": 0, + "ManufacturerSerialNumber": "", + "ComputedSerialNumber": "", + "EstimatedDeviceFirstUseTime": 0, + "ReportsTimeSinceVSync": false, + "SecondsFromVsyncToPhotons": 0.0, + "DisplayFrequency": 0.0, + "UserIpdMeters": 0.0, + "CurrentUniverseId": 0, + "PreviousUniverseId": 0, + "DisplayFirmwareVersion": 0, + "IsOnDesktop": false, + "DisplayMCType": 0, + "DisplayMCOffset": 0.0, + "DisplayMCScale": 0.0, + "EdidVendorID": 0, + "DisplayMCImageLeft": "", + "DisplayMCImageRight": "", + "DisplayGCBlackClamp": 0.0, + "EdidProductID": 0, + "DisplayGCType": 0, + "DisplayGCOffset": 0.0, + "DisplayGCScale": 0.0, + "DisplayGCPrescale": 0.0, + "DisplayGCImage": "", + "LensCenterLeftU": 0.0, + "LensCenterLeftV": 0.0, + "LensCenterRightU": 0.0, + "LensCenterRightV": 0.0, + "UserHeadToEyeDepthMeters": 0.0, + "CameraFirmwareVersion": 0, + "CameraFirmwareDescription": "", + "DisplayFPGAVersion": 0, + "DisplayBootloaderVersion": 0, + "DisplayHardwareVersion": 0, + "AudioFirmwareVersion": 0, + "CameraCompatibilityMode": 0, + "ScreenshotHorizontalFieldOfViewDegrees": 0.0, + "ScreenshotVerticalFieldOfViewDegrees": 0.0, + "DisplaySuppressed": false, + "DisplayAllowNightMode": false, + "DisplayMCImageWidth": 0, + "DisplayMCImageHeight": 0, + "DisplayMCImageNumChannels": 0, + "SecondsFromPhotonsToVblank": 0.0, + "DriverDirectModeSendsVsyncEvents": false, + "DisplayDebugMode": false, + "GraphicsAdapterLuid": 0, + "DriverProvidedChaperonePath": "", + "ExpectedTrackingReferenceCount": 0, + "ExpectedControllerCount": 0, + "NamedIconPathControllerLeftDeviceOff": "", + "NamedIconPathControllerRightDeviceOff": "", + "NamedIconPathTrackingReferenceDeviceOff": "", + "DoNotApplyPrediction": false, + "DistortionMeshResolution": 0, + "DriverIsDrawingControllers": false, + "DriverRequestsApplicationPause": false, + "DriverRequestsReducedRendering": false, + "MinimumIpdStepMeters": 0.0, + "AudioBridgeFirmwareVersion": 0, + "ImageBridgeFirmwareVersion": 0, + "ImuFactoryGyroBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryGyroScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ConfigurationIncludesLighthouse20Features": false, + "AdditionalRadioFeatures": 0, + "ExpectedControllerType": "", + "HmdTrackingStyle": 0, + "DriverProvidedChaperoneVisibility": false, + "HmdColumnCorrectionSettingPrefix": "", + "CameraSupportsCompatibilityModes": false, + "SupportsRoomViewDepthProjection": false, + "DisplaySupportsMultipleFramerates": false, + "DisplayColorMultLeft": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplayColorMultRight": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplaySupportsRuntimeFramerateChange": false, + "DisplaySupportsAnalogGain": false, + "DisplayMinAnalogGain": 0.0, + "DisplayMaxAnalogGain": 0.0, + "DashboardScale": 0.0, + "IpdUIRangeMinMeters": 0.0, + "IpdUIRangeMaxMeters": 0.0, + "HmdSupportsHDCP14LegacyCompat": false, + "HmdSupportsMicMonitoring": false, + "DriverRequestedMuraCorrectionMode": 0, + "DriverRequestedMuraFeatherInnerLeft": 0, + "DriverRequestedMuraFeatherInnerRight": 0, + "DriverRequestedMuraFeatherInnerTop": 0, + "DriverRequestedMuraFeatherInnerBottom": 0, + "DriverRequestedMuraFeatherOuterLeft": 0, + "DriverRequestedMuraFeatherOuterRight": 0, + "DriverRequestedMuraFeatherOuterTop": 0, + "DriverRequestedMuraFeatherOuterBottom": 0, + "AudioDefaultPlaybackDeviceId": "", + "AudioDefaultRecordingDeviceId": "", + "AudioDefaultPlaybackDeviceVolume": 0.0, + "AudioSupportsDualSpeakerAndJackOutput": false, + "AttachedDeviceId": "", + "SupportedButtons": 0, + "Axis0Type": 0, + "Axis1Type": 0, + "Axis2Type": 0, + "Axis3Type": 0, + "Axis4Type": 0, + "ControllerRoleHint": 0, + "FieldOfViewLeftDegrees": 0.0, + "FieldOfViewRightDegrees": 0.0, + "FieldOfViewTopDegrees": 0.0, + "FieldOfViewBottomDegrees": 0.0, + "TrackingRangeMinimumMeters": 0.0, + "TrackingRangeMaximumMeters": 0.0, + "ModeLabel": "", + "CanWirelessIdentify": false, + "Nonce": 0, + "IconPathName": "", + "NamedIconPathDeviceOff": "", + "NamedIconPathDeviceSearching": "", + "NamedIconPathDeviceSearchingAlert": "", + "NamedIconPathDeviceReady": "", + "NamedIconPathDeviceReadyAlert": "", + "NamedIconPathDeviceNotReady": "", + "NamedIconPathDeviceStandby": "", + "NamedIconPathDeviceAlertLow": "", + "NamedIconPathDeviceStandbyAlert": "", + "OverrideContainer": 0, + "UserConfigPath": "", + "InstallPath": "", + "HasDisplayComponent": false, + "HasControllerComponent": false, + "HasCameraComponent": false, + "HasDriverDirectModeComponent": false, + "HasVirtualDisplayComponent": false, + "HasSpatialAnchorsSupport": false, + "ControllerType": "", + "ControllerHandSelectionPriority": 0, + "variant": "TrackingSystemName" + }, + "content": [] + }, + "tracking_ref_only": false, + "enable_vive_tracker_proxy": false, + "face_tracking": { + "enabled": false, + "content": { + "gui_collapsed": true, + "sources": { + "combined_eye_gaze": true, + "eye_tracking_fb": true, + "face_tracking_fb": true, + "eye_expressions_htc": true, + "lip_expressions_htc": true + }, + "sink": { + "VrchatEyeOsc": { + "port": 9000 + }, + "variant": "VrchatEyeOsc" + } + } + }, + "body_tracking": { + "enabled": false, + "content": { + "gui_collapsed": true, + "sources": { + "body_tracking_fb": { + "enabled": true, + "content": { + "full_body": true + } + } + }, + "sink": { + "VrchatBodyOsc": { + "port": 9000 + }, + "variant": "FakeViveTracker" + }, + "tracked": true + } + } + }, + "connection": { + "stream_protocol": { + "variant": "Udp" + }, + "client_discovery": { + "enabled": true, + "content": { + "auto_trust_clients": false + } + }, + "on_connect_script": "", + "on_disconnect_script": "", + "avoid_video_glitching": false, + "packet_size": 1400, + "stream_port": 9944, + "web_server_port": 8082, + "osc_local_port": 9942, + "server_send_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "server_recv_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "client_send_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "client_recv_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "max_queued_server_video_frames": 1024, + "statistics_history_size": 256, + "aggressive_keyframe_resend": false, + "dscp": { + "set": false, + "content": { + "ClassSelector": 7, + "AssuredForwarding": { + "class": 4, + "drop_probability": { + "variant": "Low" + } + }, + "variant": "ExpeditedForwarding" + } + } + }, + "extra": { + "steamvr_launcher": { + "driver_launch_action": { + "variant": "UnregisterOtherDriversAtStartup" + }, + "open_close_steamvr_with_dashboard": true + }, + "capture": { + "startup_video_recording": false, + "rolling_video_files": { + "enabled": false, + "content": { + "duration_s": 5 + } + }, + "capture_frame_dir": "" + }, + "logging": { + "show_notification_tip": true, + "prefer_backtrace": false, + "notification_level": { + "variant": "Warning" + }, + "client_log_report_level": { + "enabled": true, + "content": { + "variant": "Error" + } + }, + "show_raw_events": { + "enabled": false, + "content": { + "hide_spammy_events": false + } + }, + "log_to_disk": false, + "log_tracking": false, + "log_button_presses": false, + "log_haptics": false, + "debug_groups": { + "server_impl": false, + "client_impl": false, + "server_core": false, + "client_core": false, + "connection": false, + "sockets": false, + "server_gfx": false, + "client_gfx": false, + "encoder": false, + "decoder": false + } + }, + "patches": { + "linux_async_compute": false, + "linux_async_reprojection": false + }, + "open_setup_wizard": false + } + } +} +``` + +Contents of users/jeirmeister/dotfiles/alvr/active_runtime.json: +``` +{ + "file_format_version": "1.0.0", + "runtime": { + "VALVE_runtime_is_steamvr": true, + "library_path": "/home/novaviper/.local/share/Steam/steamapps/common/SteamVR/bin/linux64/vrclient.so", + "name": "SteamVR" + } +} + +``` + +Contents of users/jeirmeister/dotfiles/kitty/default.conf: +``` +# Set the working directory for windows in the current tab +#cd ~ + +#Launch shell +launch . + +#Launch shell +launch . + +launch cava + +``` + +Contents of secrets/secrets.nix: +``` +{ config, lib, ... }: + +let + inherit (lib) filterAttrs mapAttrs; + + # Reusable keys definitions + users = { + jeirmeister = [ + "0x33A40DF62D35C4A7" # GPG key + ]; + }; + + systems = { + steamnix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJuZYkDQGN6k+uxu3npJ/PN5hwVU9c4HPU5kJCVVitGt root@steamnix"; + }; + + # Helper functions + allUsers = lib.flatten (builtins.attrValues users); + allSystems = builtins.attrValues systems; + + # Common recipient sets + commonRecipients = allUsers ++ allSystems; +in +{ + # User passwords + "jeirmeister/passwd".publicKeys = users.jeirmeister ++ allSystems; + + # SSH keys + "jeirmeister/ssh/id_ed25519".publicKeys = users.jeirmeister ++ [ systems.steamnix ]; + + # GPG keys + "jeirmeister/gpg/private".publicKeys = users.jeirmeister ++ [ systems.steamnix ]; + + # Application secrets + "jeirmeister/borg".publicKeys = users.jeirmeister; +} + +``` + +Contents of secrets/default.nix: +``` +{ config, pkgs, lib, ... }: + +{ + imports = [ + ./users + ]; + + options = { + variables.secrets = { + identityPaths = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = "List of paths to age identities for secret decryption"; + }; + + userKeys = lib.mkOption { + type = lib.types.attrsOf (lib.types.listOf lib.types.str); + default = { + jeirmeister = [ + "0x33A40DF62D35C4A7" # Your GPG key ID + ]; + }; + description = "User GPG keys for secret encryption"; + }; + }; + }; + + config = { + age = { + identityPaths = config.variables.secrets.identityPaths; + secrets = import ./secrets.nix { inherit config pkgs lib; }; + }; + }; +} + +``` + +Contents of secrets/users/default.nix: +``` +{ config, lib, ... }: + +{ + imports = [ + ./jeirmeister.nix + ]; +} + +``` + +Contents of secrets/users/jeirmeister.nix: +``` +{ config, lib, ... }: + +let + secrets = config.age.secrets; +in +{ + age.secrets = { + # SSH keys + "jeirmeister/ssh/id_ed25519" = { + file = ../encrypted/jeirmeister/ssh/id_ed25519.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # GPG keys + "jeirmeister/gpg/private" = { + file = ../encrypted/jeirmeister/gpg/private.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # System passwords + "jeirmeister/passwd" = { + file = ../encrypted/jeirmeister/passwd.age; + mode = "0440"; + }; + + }; +} + +``` + +Contents of secrets/users/jeirmeister/default.nix: +``` +{ config, lib, ... }: + +let + secrets = config.age.secrets; +in +{ + age.secrets = { + # SSH keys + "jeirmeister/ssh/id_ed25519" = { + file = ../encrypted/jeirmeister/ssh/id_ed25519.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # GPG keys + "jeirmeister/gpg/private" = { + file = ../encrypted/jeirmeister/gpg/private.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # System passwords + "jeirmeister/passwd" = { + file = ../encrypted/jeirmeister/passwd.age; + mode = "0440"; + }; + + # Application secrets + "jeirmeister/borg" = { + file = ../encrypted/jeirmeister/borg.age; + owner = "jeirmeister"; + group = "users"; + mode = "0400"; + }; + }; +} + +``` + +Contents of secrets/users/jeirmeister/_keys/_gpg/_public.key: +``` +[Could not decode file contents] + +``` + +Contents of secrets/users/jeirmeister/_keys/_gpg/_private.key: +``` +[Could not decode file contents] + +``` + +Contents of secrets/users/jeirmeister/_keys/_ssh/_id_ed25519.pub: +``` +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPThkPiDz9N2oL4yqeVIhYdM0wTGk9xH3GjFdxvSntaw jeirmeister@nixos + +``` + +Contents of secrets/users/jeirmeister/_keys/_ssh/_id_ed25519: +``` +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACD04ZD4g8/TdqC+MqnlSIWHTNMExpPcR9xoxXcb0p7WsAAAAJhsVPSrbFT0 +qwAAAAtzc2gtZWQyNTUxOQAAACD04ZD4g8/TdqC+MqnlSIWHTNMExpPcR9xoxXcb0p7WsA +AAAEDuUdKAVQz7X+5rGyfRO7yardCsauFdRXJ0/gQpIHSIo/ThkPiDz9N2oL4yqeVIhYdM +0wTGk9xH3GjFdxvSntawAAAAEWplaXJtZWlzdGVyQG5peG9zAQIDBA== +-----END OPENSSH PRIVATE KEY----- + +``` + +Contents of secrets/users/jeirmeister/passwords/_bitwarden.age: +``` + +``` + +Contents of secrets/users/jeirmeister/passwords/_tailscale.age: +``` + +``` + +Contents of secrets/users/jeirmeister/passwords/_sudo.age: +``` + +``` + +Contents of modules/core/desktop.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.modules.desktop; + waylandEnv = { + NIXOS_OZONE_WL = "1"; + MOZ_ENABLE_WAYLAND = "1"; + GDK_BACKEND = "wayland,x11"; + SDL_VIDEODRIVER = "x11"; + CLUTTER_BACKEND = "wayland"; + # QT_QPA_PLATFORM = "wayland"; + # LIBSEAT_BACKEND = "logind"; + XDG_SESSION_TYPE = "wayland"; + #WLR_NO_HARDWARE_CURSORS = "1"; + # _JAVA_AWT_WM_NONREPARENTING = "1"; + # GDK_SCALE = "2"; + # ELECTRON_OZONE_PLATFORM_HINT = "wayland"; + }; +in { + options.modules.desktop = { + enable = lib.mkEnableOption "Enable desktop configurations"; + x11.enable = lib.mkEnableOption "Enable X11 integration" // {default = true;}; + wayland.enable = lib.mkEnableOption "Enable wayland integration"; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + # X11 Configs + (lib.mkIf cfg.x11.enable { + # Enable the X11 windowing system. + services.xserver = { + enable = true; + + # Configure keymap in X11 + xkb = { + layout = "us"; + variant = ""; + options = "terminate:ctrl_alt_bksp,caps:ctrl_modifier"; + }; + + # Remove xterm terminal + excludePackages = with pkgs; [xterm]; + }; + + # Install installation + environment.systemPackages = with pkgs; [ + # X11 + xorg.xkbutils + xorg.xkill + xorg.libxcb + ]; + }) + # Wayland Configs + (lib.mkIf cfg.wayland.enable { + environment = { + # NOTE This will break stuff if there is a non-wayland user on the same machine, + # but application launchers need this. + sessionVariables = waylandEnv; + # Install necessary wayland protocol packages + systemPackages = with pkgs; [ + #xorg.xeyes + kdePackages.xwaylandvideobridge + libsForQt5.qt5.qtwayland + qt6.qtwayland + ]; + }; + + hm.home.sessionVariables = waylandEnv; + }) + + # Common + { + modules.fonts.enable = true; + services = { + # Enable touchpad support + libinput.enable = true; + # Enable color management service + colord.enable = true; + # Enable pipewire + pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + }; + pulse.enable = true; + }; + }; + environment.systemPackages = with pkgs; [ + #Notifications + libnotify + + #PDF + poppler + + # Enable guestures for touchpad + libinput-gestures + # Install audio configuration tools (Especially important for VR) + pavucontrol + pulseaudio + ]; + + # Enable the RealtimeKit system service + security.rtkit.enable = true; + + # Disable PulseAudio + hardware.pulseaudio.enable = lib.mkForce false; + + # Enable networking + networking.networkmanager.enable = true; + + # Enable for GTK + programs.dconf.enable = true; + + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + wlr.enable = true; + extraPortals = with pkgs; [xdg-desktop-portal-gtk]; + }; + + hm.xdg = { + /* + portal = { + enable = true; + xdgOpenUsePortal = true; + }; + */ + # Don't generate config at the usual place. + # Allow desktop applications to write their file association + # preferences to this file. + configFile."mimeapps.list".enable = false; + # Home-manager also writes xdg-mime-apps configuration to the + # "deprecated" location. Desktop applications will look in this + # list for associations, if no association was found in the + # previous config file. + dataFile."applications/mimeapps.list".force = true; + mimeApps.enable = true; + }; + } + ]); +} + +``` + +Contents of modules/core/age.nix: +``` +{ + config, + lib, + pkgs, + inputs, + ... +}: let + cfg = config.variables; + pcscdCfg = pkgs.writeText "reader.conf" ""; + pcscdPkg = pkgs.pcsclite; + pcscdPluginEnv = pkgs.buildEnv { + name = "pcscd-plugins"; + paths = map (p: "${p}/pcsc/drivers") [pkgs.ccid]; + }; +in + {imports = with inputs; [agenix.nixosModules.default];} + // { + options.variables.userIdentityPaths = lib.mkOption { + default = []; + type = lib.types.listOf lib.types.path; + description = "List of secret identity paths for the user"; + }; + + config = lib.mkMerge [ + (lib.mkIf (cfg.userIdentityPaths != []) { + age.identityPaths = lib.mkOptionDefault cfg.userIdentityPaths; + hm.age.identityPaths = lib.mkOptionDefault cfg.userIdentityPaths; + }) + + { + home-manager.sharedModules = with inputs; [ + agenix.homeManagerModules.default + ]; + environment.systemPackages = with pkgs; [agenix age age-plugin-yubikey]; + + age.ageBin = "PATH=$PATH:${lib.makeBinPath [pkgs.age-plugin-yubikey]} ${pkgs.age}/bin/age"; + + services.pcscd.enable = lib.mkForce true; + # TODO: Figure out why this is broken + #systemd.services.pcscd.serviceConfig.ExecStart = mkForce [ + # "${pcscdPkg}/bin/pcscd -f -c ${pcscdCfg}" + #]; + + # HACK: Start pcscd before decrypting secrets + boot.initrd.systemd = { + enable = lib.mkDefault true; + packages = [(lib.getBin pcscdPkg)]; + storePaths = [ + "${pcscdPkg}/bin/pcscd" + "${pcscdCfg}" + "${pcscdPluginEnv}" + ]; + + sockets.pcscd.wantedBy = ["sockets.target"]; + services.pcscd = { + environment.PCSCLITE_HP_DROPDIR = pcscdPluginEnv; + after = ["rollback.service"]; + serviceConfig.ExecStart = [ + "" + "${pcscdPkg}/bin/pcscd -f -c ${pcscdCfg}" + ]; + }; + }; + } + ]; + } + +``` + +Contents of modules/core/filesystem.nix: +``` +{pkgs, ...}: { + services.usbmuxd.enable = true; + + environment.systemPackages = with pkgs; [ + libimobiledevice + ifuse # optional, to mount using 'ifuse' + gvfs + usbmuxd + ]; + + boot.supportedFilesystems = [ + "btrfs" + "ext2" + "ext3" + "ext4" + "exfat" + "f2fs" + "fat8" + "fat16" + "fat32" + "ntfs" + "xfs" + ]; +} + +``` + +Contents of modules/core/networking.nix: +``` +_: { + networking.firewall.enable = true; + systemd.network.wait-online.enable = false; + systemd.services.NetworkManager-wait-online.enable = false; + + # Enable mDNS + services.avahi = { + enable = true; + nssmdns4 = true; + # for a WiFi printer + openFirewall = true; + # Make user systemd service work with avahi + publish = { + enable = true; + userServices = true; + }; + }; +} + +``` + +Contents of modules/core/xdg.nix: +``` +{ + config, + lib, + ... +}: { + environment.sessionVariables = { + XDG_CACHE_HOME = "$HOME/.cache"; + XDG_CONFIG_HOME = "$HOME/.config"; + XDG_DATA_HOME = "$HOME/.local/share"; + XDG_STATE_HOME = "$HOME/.local/state"; + + ANDROID_USER_HOME = "$XDG_DATA_HOME/android"; + CUDA_CACHE_PATH = "$XDG_CACHE_HOME/nv"; + TLDR_CACHE_DIR = "$XDG_CACHE_HOME/tldr"; + }; +} + +``` + +Contents of modules/core/ld.nix: +``` +# Taken from https://github.com/ywmaa/dotfiles/blob/main/nix-config/dynamic_binaries_support.nix +{pkgs, ...}: { + # allow running binaries + services.envfs.enable = true; + programs.nix-ld.enable = true; + programs.nix-ld.libraries = with pkgs; [ + # Needed for operating system detection until + # https://github.com/ValveSoftware/steam-for-linux/issues/5909 is resolved + lsb-release + # Errors in output without those + pciutils + # Games' dependencies + xorg.xrandr + which + # Needed by gdialog, including in the steam-runtime + perl + # Open URLs + xdg-utils + iana-etc + # Steam Play / Proton + python3 + + # It tries to execute xdg-user-dir and spams the log with command not founds + xdg-user-dirs + + # electron based launchers need newer versions of these libraries than what runtime provides + sqlite + # Godot + Blender + stdenv.cc.cc + # Blender + libdecor + # Godot Engine + libunwind + # Others + xorg.libXcomposite + xorg.libXtst + xorg.libXrandr + xorg.libXext + xorg.libX11 + xorg.libXfixes + xorg.libxkbfile + libGL + libva + libva-utils + #pipewire.lib + ocamlPackages.alsa + alsa-lib + libpulseaudio + # steamwebhelper + harfbuzz + libthai + pango + brotli + fuse3 + icu + libglvnd + libnotify + libxml2 + openssl + pipewire + pulseaudio + systemd + x264 + libplist + + lsof # friends options won't display "Launch Game" without it + file # called by steam's setup.sh + + # dependencies for mesa drivers, needed inside pressure-vessel + mesa + mesa.llvmPackages.llvm.lib + vulkan-loader + expat + wayland + xorg.libxcb + xorg.libXdamage + xorg.libxshmfence + xorg.libXxf86vm + libelf + (lib.getLib elfutils) + + # Without these it silently fails + xorg.libXinerama + xorg.libXcursor + xorg.libXrender + xorg.libXScrnSaver + xorg.libXi + xorg.libSM + xorg.libICE + gnome2.GConf + curlWithGnuTls + nspr + nss + cups + libcap + SDL2 + libusb1 + dbus + dbus-glib + gsettings-desktop-schemas + ffmpeg + libudev0-shim + + # Verified games requirements + fontconfig + freetype + xorg.libXt + xorg.libXmu + libogg + libvorbis + SDL + SDL2_image + glew110 + libidn + tbb + zlib + + # SteamVR + procps + usbutils + udev + + # Other things from runtime + glib + gtk2 + gtk3 + bzip2 + flac + freeglut + libjpeg + libpng + libpng12 + libsamplerate + libmikmod + libtheora + libtiff + pixman + speex + SDL_image + SDL_ttf + SDL_mixer + SDL2_ttf + SDL2_mixer + libappindicator-gtk2 + libappindicator-gtk3 + libdbusmenu-gtk2 + libindicator-gtk2 + libcaca + libcanberra + libgcrypt + libvpx + librsvg + xorg.libXft + libvdpau + + # required by coreutils stuff to run correctly + # Steam ends up with LD_LIBRARY_PATH=:/usr/lib: + # which overrides DT_RUNPATH in our binaries, so it tries to dynload the + # very old versions of stuff from the runtime. + # FIXME: how do we even fix this correctly + attr + + # Not formally in runtime but needed by some games + at-spi2-atk + at-spi2-core # CrossCode + gst_all_1.gstreamer + gst_all_1.gst-plugins-ugly + gst_all_1.gst-plugins-base + json-glib # paradox launcher (Stellaris) + libdrm + libxkbcommon # paradox launcher + libxcrypt # Alien Isolation, XCOM 2, Company of Heroes 2 + mono + xorg.xkeyboardconfig + xorg.libpciaccess + icu # dotnet runtime, e.g. Stardew Valley + + # screeps dependencies + atk + cairo + gdk-pixbuf + + # Prison Architect + libGLU + libuuid + libbsd + + # Loop Hero + libidn2 + libpsl + nghttp2.lib + rtmpdump + ]; +} + +``` + +Contents of modules/core/nix.nix: +``` +{ + config, + pkgs, + self, + lib, + inputs, + ... +}: { + # Config Nixpkgs + nixpkgs = { + overlays = builtins.attrValues self.overlays; + config = { + allowUnfree = true; + joypixels.acceptLicense = true; + }; + }; + + nix = { + # Makes `nix run` commands use unfree + registry = lib.mkForce { + nixpkgs.flake = inputs.nixpkgs; + nixpkgs-stable.flake = inputs.nixpkgs-stable; + + # Allow running unfree packages with nix3 commands via `nix run unfree#steam` + unfree.flake = pkgs.callPackage lib.mkUnfreeNixpkgs {path = inputs.nixpkgs;}; + unfree-stable.flake = pkgs.callPackage lib.mkUnfreeNixpkgs {path = inputs.nixpkgs-stable;}; + }; + + # Disable channels + channel.enable = false; + # Force latest nix version + package = pkgs.nixVersions.nix_2_23; + + # Perform nix store optimisation weekly to maintain low disk usage + optimise = { + automatic = true; + dates = ["weekly"]; # Optional; allows customizing optimisation schedule + }; + + # Perform garbage collection weekly to maintain low disk usage + gc = { + automatic = true; + dates = "weekly"; + # Delete generations that are more than 14 days old + options = "--delete-older-than 14d"; + }; + + settings = { + # Make sure flakes is enabled + experimental-features = ["nix-command" "flakes"]; + + # No warnings if git isn't pushed + warn-dirty = false; + + # Force XDG Base Directory paths + use-xdg-base-directories = true; + + # for Nix path + nix-path = ["nixpkgs=${pkgs.path}"]; + + # Make root and any user in the wheel group trusted + trusted-users = ["root" "@wheel"]; + + substituters = [ + "https://nix-community.cachix.org" + "https://nix-gaming.cachix.org" + ]; + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" + ]; + + # Reasonable defaults, see https://jackson.dev/post/nix-reasonable-defaults/ + connect-timeout = 5; + log-lines = 25; + min-free = 128000000; # 128MB + max-free = 1000000000; # 1GB + fallback = true; # If binary cache fails, it's okay + }; + }; + + documentation.nixos.enable = false; # Apparently speeds up rebuild time +} + +``` + +Contents of modules/core/user.nix: +``` +{ + config, + lib, + options, + username, + ... +}: let + internals = { + cfg = config.variables.user; + hostname = config.networking.hostName; + }; +in { + options.variables.user = { + fullName = lib.mkOption { + type = lib.types.str; + default = ""; + example = "John Doe"; + description = '' + Your first and last name. + ''; + }; + emailAddress = lib.mkOption { + type = lib.types.str; + default = ""; + example = "johndoe@example.com"; + description = '' + Your email address. + ''; + }; + homeDirectory = lib.mkOption { + type = lib.types.str; + description = '' + The directory for the user's folders. This should only be set if it's in a non-default location. + ''; + default = "/home/${username}"; + }; + }; + + config = { + #users.mutableUsers = false; # Makes it so we can only do password stuff via nixos, safer for not bricking system + + users.users.${username} = { + isNormalUser = true; + description = internals.cfg.fullName; + }; + + time = { + hardwareClockInLocalTime = lib.mkDefault true; + # Set UTC as default timezone, users can override if they want to + timeZone = lib.mkDefault "UTC"; + }; + + assertions = [ + #{assertion = options.variables.user.fullName.isDefined;} + #{assertion = options.variables.user.emailaddress.isDefined;} + {assertion = options.variables.user.homeDirectory.isDefined;} + ]; + }; +} + +``` + +Contents of modules/core/security.nix: +``` +_: { + # Make /tmp clean itself on remote. /tmp should be volatile storage! + boot.tmp.cleanOnBoot = true; + + boot.kernelModules = ["tcp_bbr"]; + + ## TCP hardening + boot.kernel.sysctl = { + # Prevent bogus ICMP errors from filling up logs. + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering causes the kernel to do source validation of + # packets received from all interfaces. This can mitigate IP spoofing. + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Do not accept IP source route packets (we're not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Don't send ICMP redirects (again, we're on a router) + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # Refuse ICMP redirects (MITM mitigations) + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # Protects against SYN flood attacks + "net.ipv4.tcp_syncookies" = 1; + # Incomplete protection again TIME-WAIT assassination + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # TCP Fast Open is a TCP extension that reduces network latency by packing + # data in the sender’s initial TCP SYN. Setting 3 = enable TCP Fast Open for + # both incoming and outgoing connections: + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + slight improvement in throughput & latency + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; +} + +``` + +Contents of modules/core/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + options.modules = { + core = lib.mkOption { + type = lib.types.submodule { + options = { + profile = lib.mkOption { + type = lib.types.enum [ "minimal" "workstation" "server" ]; + default = "minimal"; + description = "The core profile to use for this system"; + }; + }; + }; + }; + }; + + config = { + # Import the selected profile + imports = [ ../profiles/core/${config.modules.core.profile}.nix ]; + + # Common core settings that apply to all profiles + nix.settings.auto-optimise-store = true; + boot.tmp.cleanOnBoot = true; + }; +} + +``` + +Contents of modules/core/home-manager.nix: +``` +{ + config, + lib, + self, + inputs, + stateVersion, + hostname, + username, + ... +}: let + hm-config = config.hm; + activationScript = let + commands = builtins.concatStringsSep "\n" ( + map (file: ''rm -fv "${file}" && echo Deleted "${file}"'') hm-config.nukeFiles + ); + in '' + #!/run/current-system/sw/bin/bash + set -o errexit + set -o nounset + + echo "[home-nuker] Nuking files so Home Manager can get its will" + + ${commands} + ''; +in + { + imports = with inputs; [ + home-manager.nixosModules.home-manager + # Let us use hm as shorthand for home-manager config + (lib.mkAliasOptionModule ["hm"] ["home-manager" "users" username]) + ]; + } + // lib.utilMods.mkEnabledModule config "core.homeManager" { + # Home file nuking script that deletes stuff just before we run home-manager's activation scripts + system.userActivationScripts.home-conflict-file-nuker = lib.mkIf (hm-config.nukeFiles != []) activationScript; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = {inherit self inputs stateVersion hostname username;}; + backupFileExtension = ".bak"; + sharedModules = with inputs; + [ + #agenix.homeManagerModules.default + nix-index-database.hmModules.nix-index + plasma-manager.homeManagerModules.plasma-manager + #stylix.homeManagerModules.stylix + ] + # Import modules specific and user configs for home-manager + # TODO: Maybe make ./config in users be available to NixOS too and just pass any Home-Manager configs via hm? + ++ lib.utils.concatImports { + paths = [ + ../home + ../../users/${username}/config + ]; + }; + + # Import specific stuff for the user + users.${username} = import ../../users/${username}/${config.networking.hostName}.nix; + }; + + hm = { + nix.settings = config.nix.settings; + + programs = { + home-manager.enable = true; + emacs.enable = lib.mkDefault true; + git.enable = lib.mkDefault true; + ssh.enable = lib.mkDefault true; + gpg.enable = lib.mkDefault true; + }; + + home = { + inherit username stateVersion; + inherit (config.variables.user) homeDirectory; + preferXdgDirectories = true; + + sessionVariables = { + FLAKE = "${hm-config.home.homeDirectory}/Documents/NixConfig"; + XDG_BIN_HOME = "${hm-config.home.homeDirectory}/.local/bin"; + + ANDROID_USER_HOME = "${hm-config.xdg.dataHome}/android"; + CUDA_CACHE_PATH = "${hm-config.xdg.cacheHome}/nv"; + TLDR_CACHE_DIR = "${hm-config.xdg.cacheHome}/tldr"; + }; + sessionPath = ["${hm-config.home.sessionVariables.XDG_BIN_HOME}"]; + shellAliases.wget = ''wget --hsts-file="${hm-config.xdg.dataHome}/wget-hsts"''; + }; + + # (De)activate wanted systemd units when changing configs + systemd.user.startServices = "sd-switch"; + + # Enable HTML help page + manual.html.enable = true; + + news.display = "silent"; + + # Make sure XDG is enabled + xdg.enable = true; + + xresources.path = lib.mkForce "${hm-config.xdg.configHome}/.Xresources"; + + gtk = { + enable = true; + gtk2.configLocation = lib.mkForce "${hm-config.xdg.configHome}/gtk-2.0/gtkrc"; + }; + }; + } + +``` + +Contents of modules/core/_security/gpg.nix: +``` +{ config, lib, pkgs, ... }: + +lib.utilMods.mkModule config "security.gpg" { + programs.gpg = { + enable = true; + settings = { + # Modern cipher preferences + personal-cipher-preferences = "AES256 AES192 AES"; + personal-digest-preferences = "SHA512 SHA384 SHA256"; + personal-compress-preferences = "ZLIB BZIP2 ZIP Uncompressed"; + default-preference-list = "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed"; + + # Security settings + require-cross-certification = true; + no-emit-version = true; + no-comments = true; + keyid-format = "0xlong"; + with-fingerprint = true; + list-options = "show-uid-validity"; + verify-options = "show-uid-validity"; + }; + }; + + services.gpg-agent = { + enable = true; + enableSshSupport = true; + defaultCacheTtl = 1800; + maxCacheTtl = 7200; + extraConfig = '' + allow-preset-passphrase + allow-loopback-pinentry + enable-ssh-support + write-env-file + ''; + }; + + # Ensure proper GPG directory permissions on activation + home.activation.fixGpgPerms = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + if [ -d "$HOME/.gnupg" ]; then + chmod 700 "$HOME/.gnupg" + find "$HOME/.gnupg" -type f -exec chmod 600 {} \; + find "$HOME/.gnupg" -type d -exec chmod 700 {} \; + fi + ''; +} + +``` + +Contents of modules/core/_security/hardening.nix: +``` +{ config, lib, ... }: + +lib.utilMods.mkModule config "security.hardening" { + # TCP hardening from your original config + boot.kernelModules = [ "tcp_bbr" ]; + boot.kernel.sysctl = { + # Prevent bogus ICMP errors from filling up logs + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # Reverse path filtering for IP spoofing mitigation + "net.ipv4.conf.default.rp_filter" = 1; + "net.ipv4.conf.all.rp_filter" = 1; + # Disable IP source routing (we're not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # Disable ICMP redirects + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # MITM mitigations + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # SYN flood protection + "net.ipv4.tcp_syncookies" = 1; + # TIME-WAIT assassination protection + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # Enable TCP Fast Open + "net.ipv4.tcp_fastopen" = 3; + # Bufferbloat mitigations + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; + + # Make /tmp volatile + boot.tmp.cleanOnBoot = true; + + # Basic security settings + security = { + # Prevent replacing the running kernel image + protectKernelImage = true; + # Allow terminal users to execute programs + pam.loginLimits = [{ + domain = "@users"; + item = "nofile"; + type = "soft"; + value = 4096; + }]; + }; +} + +``` + +Contents of modules/core/_security/default.nix: +``` +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./gpg.nix + ./ssh.nix + ./hardening.nix + ]; +} + +``` + +Contents of modules/core/_security/ssh.nix: +``` +{ config, lib, pkgs, ... }: + +lib.utilMods.mkModule config "security.ssh" { + services.openssh = { + enable = true; + settings = { + # Security hardening + PasswordAuthentication = false; + PermitRootLogin = "no"; + # Automatically remove stale sockets + StreamLocalBindUnlink = "yes"; + }; + }; + + programs.ssh = { + startAgent = true; + extraConfig = '' + AddKeysToAgent yes + UseKeychain yes + IdentitiesOnly yes + HashKnownHosts yes + ''; + + # For better security + serverAliveInterval = 60; + serverAliveCountMax = 2; + }; + + # Ensure SSH directory exists with correct permissions + home.file.".ssh/.keep".text = ""; + home.activation.sshPermissions = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + chmod 700 ~/.ssh + if [ -f ~/.ssh/id_ed25519 ]; then + chmod 600 ~/.ssh/id_ed25519 + chmod 644 ~/.ssh/id_ed25519.pub + fi + ''; +} + +``` + +Contents of modules/home/defaults.nix: +``` +{ + config, + osConfig, + lib, + ... +}: let + cfg = config.variables; +in { + options.variables = { + defaultTerminal = lib.mkOption { + default = + if osConfig.modules.desktop.enable + then (throw "defaultTerminal not set") + else null; + type = lib.types.str; + }; + + defaultBrowser = lib.mkOption { + default = + if osConfig.modules.desktop.enable + then (throw "defaultBrowser not set") + else null; + type = lib.types.str; + }; + + defaultTextEditor = lib.mkOption { + default = ""; + type = lib.types.str; + }; + }; + + config = lib.mkMerge [ + (lib.mkIf ((lib.conds.runsDesktop osConfig) && cfg.defaultTerminal != null) { + home.sessionVariables.TERMINAL = cfg.defaultTerminal; + + modules.${cfg.defaultTerminal}.enable = true; + }) + + (lib.mkIf ((lib.conds.runsDesktop osConfig) && cfg.defaultBrowser != null) { + modules.${cfg.defaultBrowser}.enable = true; + }) + + (lib.mkIf (cfg.defaultTextEditor != null) { + modules.${cfg.defaultTextEditor}.enable = true; + }) + ]; +} + +``` + +Contents of modules/home/media/obs-studio.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "obs-studio" { + # Makes OBS Virtual Camera feature function + boot.extraModulePackages = with config.boot.kernelPackages; [v4l2loopback]; + + hm.programs.obs-studio.enable = true; + hm.programs.obs-studio.plugins = with pkgs.obs-studio-plugins; [ + obs-vkcapture + obs-pipewire-audio-capture + ]; +} + +``` + +Contents of modules/home/media/gaming.nix: +``` +{ + config, + lib, + pkgs, + username, + ... +}: let + cfg = config.modules.gaming; + hm-config = config.hm; +in + lib.utilMods.mkModule' config "gaming" { + minecraft-server.enable = lib.mkEnableOption "Enable minecraft server configs"; + vr.enable = lib.mkEnableOption "Enable virual reality configs"; + } (lib.mkMerge [ + # Minecraft + (lib.mkIf cfg.minecraft-server.enable { + # Allow Minecraft server ports + networking.firewall.allowedTCPPorts = [25565 24454]; + + hm.home.packages = with pkgs; [prismlauncher flite orca]; + hm.programs.java.enable = true; + hm.home.shellAliases = { + start-minecraft-server = "cd ~/Games/MinecraftServer-1.21.x/ && ./run.sh --nogui && cd || cd"; + start-minecraft-fabric-server = "cd ~/Games/MinecraftFabricServer-1.20.1/ && java -Xmx8G -jar ./fabric-server-mc.1.20.1-loader.0.15.7-launcher.1.0.0.jar nogui && cd || cd"; + }; + }) + # VR + (lib.mkIf cfg.vr.enable { + environment.systemPackages = with pkgs; [ + android-tools + android-udev-rules + BeatSaberModManager + helvum + ]; + + # Enable ALVR module on NixOS + programs.alvr.enable = true; + programs.alvr.openFirewall = true; + + # Fixes issue with SteamVR not starting + system.activationScripts.fixSteamVR = "${pkgs.libcap}/bin/setcap CAP_SYS_NICE+ep /home/${username}/.local/share/Steam/steamapps/common/SteamVR/bin/linux64/vrcompositor-launcher"; + + hm.xdg.desktopEntries = { + "BeatSaberModManager" = { + name = "Beat Saber ModManager"; + genericName = "Game"; + exec = "BeatSaberModManager"; + icon = "${pkgs.BeatSaberModManager}/lib/BeatSaberModManager/Resources/Icons/Icon.ico"; + type = "Application"; + categories = ["Game"]; + startupNotify = true; + comment = "Beat Saber ModManager is a mod manager for Beat Saber"; + }; + }; + }) + + # Common + { + # Enable Steam hardware compatibility + hardware.steam-hardware.enable = true; + + # Fixes SteamLink/Remote play crashing + environment.systemPackages = with pkgs; [protontricks keyutils goverlay ludusavi libcanberra protonup-qt]; + + environment.sessionVariables.ICED_BACKEND = "tiny-skia"; + hardware.graphics = { + enable = true; + enable32Bit = true; + }; + + programs.gamemode = { + enable = true; + enableRenice = true; + settings = { + general = { + softrealtime = "off"; + inhibit_screensaver = 1; + }; + custom = { + start = "''${pkgs.libnotify}/bin/notify-send 'GameMode started'"; + end = "''${pkgs.libnotify}/bin/notify-send 'GameMode ended'"; + }; + }; + }; + + programs.steam = { + enable = true; + # Make Steam folder spawn in ~/.config instead of /home/USER + package = pkgs.steam.override { + extraEnv.HOME = "/home/${username}/.config"; + extraLibraries = pkgs: [pkgs.xorg.libxcb]; + }; + remotePlay.openFirewall = true; + }; + + xdg.mime = { + defaultApplications."x-scheme-handler/steam" = "steam.desktop"; + addedAssociations."x-scheme-handler/steam" = "steam.desktop"; + }; + + hm.xdg = { + userDirs.extraConfig.XDG_GAME_DIR = "${hm-config.home.homeDirectory}/Games"; + + mimeApps = { + defaultApplications."x-scheme-handler/steam" = "steam.desktop"; + associations.added."x-scheme-handler/steam" = "steam.desktop"; + }; + }; + + hm.programs.mangohud = { + enable = true; + settings = { + ### From https://github.com/flightlessmango/MangoHud/blob/master/data/MangoHud.conf + ### MangoHud configuration file + ### Uncomment any options you wish to enable. Default options are left uncommented + ### Use some_parameter=0 to disable a parameter (only works with on/off parameters) + ### Everything below can be used / overridden with the environment variable MANGOHUD_CONFIG instead + + ################ INFORMATIONAL ################# + ## prints possible options on stdout + # help = true; + + ################ PERFORMANCE ################# + + ### Limit the application FPS. Comma-separated list of one or more FPS values (e.g. 0,30,60). 0 means unlimited (unless VSynced) + # fps_limit = 0; + + ### early = wait before present, late = wait after present + # fps_limit_method = ""; + + ### VSync [0-3] 0 = adaptive; 1 = off; 2 = mailbox; 3 = on + # vsync = -1; + + ### OpenGL VSync [0-N] 0 = off; >=1 = wait for N v-blanks, N > 1 acts as a FPS limiter (FPS = display refresh rate / N) + # gl_vsync = -2; + + ### Mip-map LoD bias. Negative values will increase texture sharpness (and aliasing) + ## Positive values will increase texture blurriness (-16 to 16) + # picmip = -17; + + ### Anisotropic filtering level. Improves sharpness of textures viewed at an angle (0 to 16) + # af = -1; + + ### Force bicubic filtering + # bicubic = true; + + ### Force trilinear filtering + # trilinear = true; + + ### Disable linear texture filtering. Makes textures look blocky + # retro = true; + + ################### VISUAL ################### + + ### Legacy layout + # legacy_layout = 0; + + ### pre defined presets + # -1 = default + # 0 = no display + # 1 = fps only + # 2 = horizontal view + # 3 = extended + # 4 = high detailed information + # preset = -1; + + ### Enable most of the toggleable parameters (currently excludes `histogram`) + # full = true; + + ### Show FPS only. ***Not meant to be used with other display params*** + # fps_only = true; + + ### Display custom centered text, useful for a header + # custom_text_center = ""; + + ### Display the current system time + # time = true; + + ### Time formatting examples + ## %H:%M + ## [ %T %F ] + ## %X # locally formatted time, because of limited glyph range, missing characters may show as '?' (e.g. Japanese) + # time_format = "%T"; + + ### Display MangoHud version + # version = true; + + ### Display the current GPU information + ## Note: gpu_mem_clock and gpu_mem_temp also need "vram" to be enabled + gpu_stats = true; + gpu_temp = true; + # gpu_junction_temp = true; + # gpu_core_clock = true; + # gpu_mem_temp = true; + # gpu_mem_clock = true; + # gpu_power = true; + # gpu_text = ""; + gpu_load_change = true; + #gpu_load_value = [ "60" "90" ]; + #gpu_load_color = [ "39F900" "FDFD09" "B22222" ]; + ## GPU fan in rpm (only works on AMD GPUs) + # gpu_fan = true; + # gpu_voltage = true; # (only works on AMD GPUs) + + ### Display the current CPU information + cpu_stats = true; + cpu_temp = true; + # cpu_power = true; + # cpu_text = ""; + # cpu_mhz = true; + cpu_load_change = true; + #cpu_load_value = [ "60" "90" ]; + #cpu_load_color = [ "39F900" "FDFD09" "B22222" ]; + + ### Display the current CPU load & frequency for each core + # core_load = true; + # core_load_change = true; + + ### Display IO read and write for the app (not system) + # io_read = true; + # io_write = true; + + ### Display system vram / ram / swap space usage + vram = true; + ram = true; + # swap = true; + + ### Display per process memory usage + ## Show resident memory and other types, if enabled + # procmem = true; + # procmem_shared = true; + # procmem_virt = true; + + ### Display battery information + # battery = true; + # battery_icon = true; + # gamepad_battery = true; + # gamepad_battery_icon = true; + # battery_watt = true; + # battery_time = true; + + ### Display FPS and frametime + fps = true; + # fps_sampling_period = 500; + # fps_color_change = true; + # fps_value = ["30" "60"]; + # fps_color=["22222" "FDFD09" "39F900"]; + frametime = true; + # frame_count = true; + + ### Display GPU throttling status based on Power, current, temp or "other" + ## Only shows if throttling is currently happening + throttling_status = true; + + ### Display miscellaneous information + # engine_version = true; + # engine_short_names = true; + # gpu_name = true; + # vulkan_driver = true; + # wine = true; + # exec_name = true; + + ### Display loaded MangoHud architecture + # arch = true; + + ### Display the frametime line graph + frame_timing = true; + # histogram = true; + + ### Display GameMode / vkBasalt running status + # gamemode = true; + # vkbasalt = true; + + ### Gamescope related options + ## Display the status of FSR (only works in gamescope) + # fsr = true; + ## Hides the sharpness info for the `fsr` option (only available in gamescope) + # hide_fsr_sharpness = true; + ## Shows the graph of gamescope app frametimes and latency (only on gamescope obviously) + # debug = true; + + ### graphs displays one or more graphs that you chose + ## seperated by ",", available graphs are + ## gpu_load,cpu_load,gpu_core_clock,gpu_mem_clock,vram,ram,cpu_temp,gpu_temp + # graphs = [""]; + + ### mangoapp related options + ## Enables mangoapp to be displayed above the Steam UI + # mangoapp_steam = true; + + ### Steam Deck options + ## Shows the Steam Deck fan rpm + # fan = true; + + ### Display current FPS limit + show_fps_limit = true; + + ### Display the current resolution + # resolution = true; + + ### Display custom text + # custom_text = ""; + ### Display output of Bash command in next column + # exec = ""; + + ### Display media player metadata + # media_player = true; + ## for example spotify + # media_player_name = ""; + ## Format metadata, lines are delimited by ; (wip) + ## example: {title};{artist};{album} + ## example: Track:;{title};By:;{artist};From:;{album} + # media_player_format = ["title" "artist" "album"]; + + ### Change the hud font size + # font_size = 24; + # font_scale = 1.0; + # font_size_text = 24; + # font_scale_media_player = 0.55; + # no_small_font = true; + + ### Change default font (set location to TTF/OTF file) + ## Set font for the whole hud + # font_file = ""; + + ## Set font only for text like media player metadata + # font_file_text = ""; + + ## Set font glyph ranges. Defaults to Latin-only. Don't forget to set font_file/font_file_text to font that supports these + ## Probably don't enable all at once because of memory usage and hardware limits concerns + ## If you experience crashes or text is just squares, reduce glyph range or reduce font size + # font_glyph_ranges = ["korean" "chinese" "chinese_simplified" "japanese" "cyrillic" "thai" "vietnamese" "latin_ext_a" "latin_ext_b"]; + + ### Outline text + text_outline = true; + # text_outline_color = 000000; + # text_outline_thickness = 1.5; + + ### Change the hud position + # position = "top-left"; + + ### Change the corner roundness + # round_corners = 0; + + ### Remove margins around MangoHud + # hud_no_margin = true; + + ### Display compact version of MangoHud + # hud_compact = true; + + ### Display MangoHud in a horizontal position + # horizontal = true; + # horizontal_stretch = true; + + ### Disable / hide the hud by default + # no_display = true; + + ### Hud position offset + # offset_x = 0; + # offset_y = 0; + + ### Hud dimensions + # width = 0; + # height = 140; + # table_columns = 3; + # cellpadding_y = -0.085; + + ### Hud transparency / alpha + # background_alpha = 0.5; + # alpha = 1.0; + + ### FCAT overlay + ### This enables an FCAT overlay to perform frametime analysis on the final image stream. + ### Enable the overlay + # fcat = true; + ### Set the width of the FCAT overlay. + ### 24 is a performance optimization on AMD GPUs that should not have adverse effects on nVidia GPUs. + ### A minimum of 20 pixels is recommended by nVidia. + # fcat_overlay_width = 24; + ### Set the screen edge, this can be useful for special displays that don't update from top edge to bottom. This goes from 0 (left side) to 3 (top edge), counter-clockwise. + # fcat_screen_edge = 0; + + ### Color customization + # text_color = "FFFFFF"; + # gpu_color = "2E9762"; + # cpu_color = "2E97CB"; + # vram_color = "AD64C1"; + # ram_color = "C26693"; + # engine_color = "EB5B5B"; + # io_color = "A491D3"; + # frametime_color = "00FF00"; + # background_color = "020202"; + # media_player_color = "FFFFFF"; + # wine_color = "EB5B5B"; + # battery_color = "FF9078"; + + ### Specify GPU with PCI bus ID for AMDGPU and NVML stats + ### Set to 'domain:bus:slot.function' + # pci_dev = "0:0a:0.0"; + + ### Blacklist + # blacklist = ""; + + ### Control over socket + ### Enable and set socket name, '%p' is replaced with process id + ## example: mangohud + ## example: mangohud-%p + # control = -1; + + ################ WORKAROUNDS ################# + ### Options starting with "gl_*" are for OpenGL + ### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable + # gl_size_query = "viewport"; + + ### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III + # gl_bind_framebuffer = 0; + + ### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx + # gl_dont_flip = 1; + + ################ INTERACTION ################# + + ### Change toggle keybinds for the hud & logging + toggle_hud = "Shift_R+F12"; + # toggle_hud_position = "Shift_R+F11"; + # toggle_fps_limit = "Shift_L+F1"; + toggle_logging = "Shift_L+F2"; + # reload_cfg = "Shift_L+F4"; + # upload_log = "Shift_L+F3"; + + #################### LOG ##################### + ### Automatically start the log after X seconds + # autostart_log = ""; + ### Set amount of time in seconds that the logging will run for + # log_duration = ""; + ### Change the default log interval, 0 is default + # log_interval = 0; + ### Set location of the output files (required for logging) + output_folder = "${hm-config.xdg.stateHome}/mangologs"; + ### Permit uploading logs directly to FlightlessMango.com + ## set to 1 to enable + # permit_upload = 0; + ### Define a '+'-separated list of percentiles shown in the benchmark results + ### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1 + ## example: ['97', 'AVG', '1', '0.1'] + # benchmark_percentiles = ["97" "AVG"]; + ## Adds more headers and information such as versioning to the log. This format is not supported on flightlessmango.com (yet) + # log_versioning = true; + ## Enable automatic uploads of logs to flightlessmango.com + # upload_logs = true; + }; + }; + } + ]) + +``` + +Contents of modules/home/terminal/kitty.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "kitty" { + #modules.fonts.enable = true; + + xdg.mimeApps = let + defaultApplications = { + "mimetype" = "kitty.desktop"; + "application/x-terminal-emulator" = "kitty.desktop"; + "x-terminal-emulator" = "kitty.desktop"; + }; + in + lib.mkIf (config.variables.defaultTerminal == "kitty") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.kitty.enable = true; + + programs.kitty.environment = { + COLORTERM = "truecolor"; + WINIT_X11_SCALE_FACTOR = "1"; + }; + + programs.kitty.settings = { + # Advanced {{{ + term = "xterm-256color"; + #shell = "${pkgs.zsh}/bin/zsh --login --interactive"; + #kitty_mod = "ctrl+shift"; + #startup_session = "default.conf"; + repaint_delay = 0; + # }}} + + # Terminal Bell {{{ + enable_audio_bell = "yes"; + visual_bell_duration = "0.0"; + bell_on_tab = "🔔 "; + linux_bell_theme = "__ocean"; + bell_path = "${pkgs.kdePackages.ocean-sound-theme}/share/sounds/ocean/stereo/bell-window-system.oga"; + # }}} + + # Cursor {{{ + cursor_shape = "block"; + cursor_blink_interval = "0.5"; + # }}} + + # Scrollback {{{ + scrollback_lines = 5000; + # }}} + + # Mouse {{{ + show_hyperlink_targets = "yes"; + copy_on_select = "yes"; + paste_actions = "quote-urls-at-prompt,confirm-if-large"; + focus_follows_mouse = "yes"; + mouse_hide_wait = 0; + # }}} + + # Window Layout {{{ + remember_window_size = "yes"; + # FIXME: Add fonts for machine types + /* + initial_window_width = + if (config.variables.machine.buildType == "laptop") + then 1000 + else 1920; + initial_window_height = + if (config.variables.machine.buildType == "laptop") + then 700 + else 1080; + */ + + enabled_layouts = "tall:bias=65;full_size=1;mirrored=false"; + # }}} + + # Color Scheme {{{ + dynamic_background_opacity = "yes"; + # }}} + }; + programs.kitty.keybindings = { + #: Window management {{{ + #: New window + #"kitty_mod+enter" = "new_window"; + #"f7" = "focus_visible_window"; + #"f8" = "swap_with_window"; + + #"ctrl+left" = "resize_window narrower"; + #"ctrl+right" = "resize_window wider"; + #"ctrl+up" = "resize_window taller"; + #"ctrl+down" = "resize_window shorter"; + + # reset all windows in the tab to default sizes + #"kitty_mod+z" = "resize_window reset"; + + # }}} + + #: Tab Management {{{ + #"ctrl+t" = "new_tab"; + # }}} + + # Font Sizes {{{ + #: Increase font size + "ctrl+equal" = "change_font_size all +1.0"; + + #: Decrease font size + "ctrl+minus" = "change_font_size all -1.0"; + + "ctrl+0" = "change_font_size all 0"; + # }}} + + #: Miscellaneous {{{ + #: Show documentation + "f9" = "show_kitty_doc overview"; + + #: Toggle fullscreen + "f11" = "toggle_fullscreen"; + + #: Toggle maximized + "f10" = "toggle_maximized"; + + #: Edit config file + #"f2" = "launch --type=tab emacsclient -nw ~/.config/kitty/kitty.conf"; + + #: Reload kitty.conf + "f5" = "combine : load_config_file : launch --type=overlay --hold --allow-remote-control kitty @ send-text 'kitty config reloaded'"; + #"ctrl+r" = "combine : load_config_file : launch --type=overlay --hold --allow-remote-control kitty @ send-text 'kitty config reloaded'"; + #: Debug kitty configuration + "f6" = "debug_config"; + # }}} + }; +} + +``` + +Contents of modules/home/terminal/konsole.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "konsole" { + xdg.mimeApps = let + defaultApplications = { + "mimetype" = "konsole.desktop"; + "application/x-terminal-emulator" = "konsole.desktop"; + "x-terminal-emulator" = "konsole.desktop"; + }; + in + lib.mkIf (config.variables.defaultTerminal == "konsole") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + # DefaultThemed profile is considered the Stylix module + programs.konsole.enable = true; +} + +``` + +Contents of modules/home/theme/stylix.nix: +``` +{ + config, + osConfig, + lib, + ... +}: let + cfg = config.theme.stylix; + c = config.lib.stylix.colors.withHashtag; + f = config.stylix.fonts; +in { + options.theme.stylix = { + enable = lib.mkEnableOption "Enable Stylix" // {default = osConfig.stylix.enable;}; + }; + + config = + lib.mkIf cfg.enable + (lib.mkMerge [ + (lib.mkIf (config.variables.defaultTerminal == "konsole") { + programs.konsole = { + defaultProfile = "DefaultThemed"; + profiles.DefaultThemed = { + name = "DefaultThemed"; + colorScheme = "Stylix"; + font = { + name = "${config.stylix.fonts.monospace.name}"; + size = config.stylix.fonts.sizes.terminal; + }; + }; + }; + + xdg = { + dataFile = { + "konsole/Stylix.colorscheme".source = config.lib.stylix.colors { + template = builtins.readFile ./konsole.mustache; + extension = ".colorscheme"; + }; + /* + "yakuake/skins/Dracula".source = fetchGit { + url = "https://github.com/dracula/yakuake"; + rev = "591a705898763167dd5aca2289d170f91a85aa56"; + }; + */ + }; + }; + }) + { + nukeFiles = ["${config.home.homeDirectory}/.config/gtk-2.0/gtkrc" "${config.home.homeDirectory}/.config/gtk-3.0/gtk.css" "${config.home.homeDirectory}/.config/gtk-4.0/gtk.css" "${config.home.homeDirectory}/.gtkrc-2.0"]; + + gtk = lib.mkIf (config.stylix.polarity == "dark") { + enable = true; + theme.name = lib.mkForce "adw-gtk3-dark"; + gtk3.extraConfig = {gtk-application-prefer-dark-theme = true;}; + gtk4.extraConfig = {gtk-application-prefer-dark-theme = true;}; + }; + + programs = { + rio.settings = { + window.opacity = config.stylix.opacity.terminal; + fonts = { + size = f.sizes.terminal + 3; # Make it larger because fonts are really tiny using default stylix font size + family = "${f.monospace.name}"; + emoji = { + family = "${f.emoji.name}"; + }; + }; + }; + plasma = { + overrideConfig = true; + workspace.cursor = { + theme = "${config.stylix.cursor.name}"; + inherit (config.stylix.cursor) size; + }; + fonts = let + general = { + family = "${f.sansSerif.name}"; + pointSize = f.sizes.applications; + }; + small = { + inherit (general) family; + pointSize = f.sizes.desktop; + }; + in { + inherit general small; + fixedWidth = { + family = "${f.monospace.name}"; + pointSize = f.sizes.terminal; + }; + toolbar = small; + menu = small; + windowTitle = small; + }; + }; + + zsh.syntaxHighlighting.styles = { + ## General + ### Diffs + ### Markup + ## Classes + # Comments + comment = "fg=${c.base04}"; + ## Constants + ## Entitites + ## Functions/methods + alias = "fg=${c.base0B}"; + suffix-alias = "fg=${c.base0B}"; + global-alias = "fg=${c.base0B}"; + function = "fg=${c.base0B}"; + command = "fg=${c.base0B}"; + precommand = "fg=${c.base0B},italic"; + autodirectory = "fg=${c.base09},italic"; + single-hyphen-option = "fg=${c.base09}"; + double-hyphen-option = "fg=${c.base09}"; + back-quoted-argument = "fg=${c.base0E}"; + ## Keywords + ## Built ins + builtin = "fg=${c.base0B}"; + reserved-word = "fg=${c.base0B}"; + hashed-command = "fg=${c.base0B}"; + ## Punctuation + commandseparator = "fg=${c.base08}"; + command-substitution-delimiter = "fg=${c.base05}"; + command-substitution-delimiter-unquoted = "fg=${c.base05}"; + process-substitution-delimiter = "fg=${c.base05}"; + back-quoted-argument-delimiter = "fg=${c.base08}"; + back-double-quoted-argument = "fg=${c.base08}"; + back-dollar-quoted-argument = "fg=${c.base08}"; + ## Serializable / Configuration Languages + ## Storage + ## Strings + command-substitution-quoted = "fg=${c.base0A}"; + command-substitution-delimiter-quoted = "fg=${c.base0A}"; + single-quoted-argument = "fg=${c.base0A}"; + single-quoted-argument-unclosed = "fg=${c.base08},bold"; + double-quoted-argument = "fg=${c.base0A}"; + double-quoted-argument-unclosed = "fg=${c.base08},bold"; + rc-quote = "fg=${c.base0A}"; + ## Variables + dollar-quoted-argument = "fg=${c.base05}"; + dollar-quoted-argument-unclosed = "fg=${c.base08},bold"; + dollar-double-quoted-argument = "fg=${c.base05}"; + assign = "fg=${c.base05}"; + named-fd = "fg=${c.base05}"; + numeric-fd = "fg=${c.base05}"; + ## No category relevant in spec + unknown-token = "fg=${c.base08},bold"; + path = "fg=${c.base05}"; + path_pathseparator = "fg=${c.base08}"; + path_prefix = "fg=${c.base05}"; + path_prefix_pathseparator = "fg=${c.base08}"; + globbing = "fg=${c.base05}"; + history-expansion = "fg=${c.base0E}"; + #command-substitution ="fg=?"; + #command-substitution-unquoted ="fg=?"; + #process-substitution ="fg=?"; + #arithmetic-expansion ="fg=?"; + back-quoted-argument-unclosed = "fg=${c.base08},bold"; + redirection = "fg=${c.base05}"; + arg0 = "fg=${c.base05}"; + default = "fg=${c.base05}"; + cursor = "fg=${c.base05}"; + }; + }; + } + ]); +} + +``` + +Contents of modules/home/theme/konsole.mustache: +``` +[Background] +Color={{base00-rgb-r}},{{base00-rgb-g}},{{base00-rgb-b}} + +[BackgroundIntense] +Color={{base03-rgb-r}},{{base03-rgb-g}},{{base03-rgb-b}} + +[Color0] +Color={{base00-rgb-r}},{{base00-rgb-g}},{{base00-rgb-b}} + +[Color0Intense] +Color={{base03-rgb-r}},{{base03-rgb-g}},{{base03-rgb-b}} + +[Color1] +Color={{base08-rgb-r}},{{base08-rgb-g}},{{base08-rgb-b}} + +[Color1Intense] +Color={{base08-rgb-r}},{{base08-rgb-g}},{{base08-rgb-b}} + +[Color2] +Color={{base0B-rgb-r}},{{base0B-rgb-g}},{{base0B-rgb-b}} + +[Color2Intense] +Color={{base0B-rgb-r}},{{base0B-rgb-g}},{{base0B-rgb-b}} + +[Color3] +Color={{base0A-rgb-r}},{{base0A-rgb-g}},{{base0A-rgb-b}} + +[Color3Intense] +Color={{base0A-rgb-r}},{{base0A-rgb-g}},{{base0A-rgb-b}} + +[Color4] +Color={{base0D-rgb-r}},{{base0D-rgb-g}},{{base0D-rgb-b}} + +[Color4Intense] +Color={{base0D-rgb-r}},{{base0D-rgb-g}},{{base0D-rgb-b}} + +[Color5] +Color={{base0E-rgb-r}},{{base0E-rgb-g}},{{base0E-rgb-b}} + +[Color5Intense] +Color={{base0E-rgb-r}},{{base0E-rgb-g}},{{base0E-rgb-b}} + +[Color6] +Color={{base0C-rgb-r}},{{base0C-rgb-g}},{{base0C-rgb-b}} + +[Color6Intense] +Color={{base0C-rgb-r}},{{base0C-rgb-g}},{{base0C-rgb-b}} + +[Color7] +Color={{base05-rgb-r}},{{base05-rgb-g}},{{base05-rgb-b}} + +[Color7Intense] +Color={{base07-rgb-r}},{{base07-rgb-g}},{{base07-rgb-b}} + +[Foreground] +Color={{base05-rgb-r}},{{base05-rgb-g}},{{base05-rgb-b}} + +[ForegroundIntense] +Color={{base07-rgb-r}},{{base07-rgb-g}},{{base07-rgb-b}} + +[General] +Description=Base16 {{scheme-name}} +Opacity=1 +Wallpaper= + +``` + +Contents of modules/home/theme/common.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) types mkOption literalExpression mkIf mkMerge mkBefore; + cfg = config.theme; + cfgapp = cfg.app; + + iconThemeModule = types.submodule { + options = { + package = mkOption { + type = types.nullOr types.package; + default = null; + example = literalExpression "pkgs.papirus-icon-theme"; + description = '' + Package providing the theme. This package will be installed to your profile. If 'null', then the theme is assumed to be already available in your profile. + ''; + }; + name = mkOption { + type = types.str; + default = ""; + example = "Papirus-Dark"; + description = "The symbolic name of the theme within the package without any spaces."; + }; + }; + }; + + appModule = types.submodule { + options = { + rio.name = mkOption { + type = types.str; + default = ""; + example = "3024 Night"; + description = '' + The name of the theme within the package to use for Rio. + + See theme names: https://github.com/raphamorim/rio-terminal-themes/tree/main/themes + ''; + }; + }; + }; +in { + options.theme = { + packages = mkOption { + type = types.listOf types.package; + default = []; + example = literalExpression "with pkgs; [ dracula-theme ]"; + description = '' + Packages providing the theme. The list of packages will be installed to your profile. If empty, then the theme is assumed to be already available in your profile. + ''; + }; + name = mkOption { + type = types.str; + default = ""; + example = "Dracula"; + description = "The name of the theme within the package."; + }; + nameSymbolic = mkOption { + type = types.str; + default = ""; + example = "dracula"; + description = "The symbolic name of the theme within the package without any spaces."; + }; + iconTheme = mkOption { + type = types.nullOr iconThemeModule; + default = {}; + description = "Icon configuration options."; + }; + app = mkOption { + type = types.nullOr appModule; + default = {}; + description = "App theme configuration options."; + }; + }; + + config = mkIf (cfg != null) (mkMerge [ + # Configure rio + (mkIf (cfgapp != null && config.programs.rio.enable) { + xdg.configFile."rio/themes/${cfgapp.rio.name}.toml".source = + fetchGit { + url = "https://github.com/raphamorim/rio-terminal-themes"; + rev = "9d76eb416c1cc46f959f236fdfa5479a19c0a070"; + } + + "/themes/${cfgapp.rio.name}.toml"; + programs.rio.settings = mkBefore { + # It makes Rio look for the specified theme in the themes folder + # (macos and linux: ~/.config/rio/themes/dracula.toml) + # (windows: C:\Users\USER\AppData\Local\rio\themes\dracula.toml) + theme = "${cfgapp.rio.name}"; + }; + }) + # Configure gtk theme + (mkIf config.gtk.enable { + gtk = { + iconTheme = mkIf (cfg.iconTheme != null) { + inherit (cfg.iconTheme) name; + inherit (cfg.iconTheme) package; + }; + }; + }) + + { + nukeFiles = ["${config.home.homeDirectory}/.config/gtk-2.0/gtkrc" "${config.home.homeDirectory}/.config/gtk-3.0/gtk.css" "${config.home.homeDirectory}/.config/gtk-4.0/gtk.css" "${config.home.homeDirectory}/.gtkrc-2.0"]; + programs.plasma.workspace.iconTheme = "${cfg.iconTheme.name}"; + # Install the packages + home.packages = with pkgs; (mkMerge + [ + (mkIf (cfg.packages != []) cfg.packages) + (mkIf (cfg.iconTheme.package != null) [cfg.iconTheme.package]) + ]); + } + ]); +} + +``` + +Contents of modules/home/firefox/extensions.nix: +``` +{pkgs, ...}: +with pkgs.nur.repos.rycee.firefox-addons; [ + ublock-origin + sponsorblock + return-youtube-dislikes + darkreader + #bypass-paywalls-clean + plasma-integration + enhancer-for-youtube + indie-wiki-buddy + stylus + canvasblocker +] + +``` + +Contents of modules/home/firefox/firefox.nix: +``` +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "firefox" { + xdg.mimeApps = let + defaultApplications = { + "default-web-browser" = ["firefox.desktop"]; + "text/html" = ["firefox.desktop"]; + "x-scheme-handler/http" = ["firefox.desktop"]; + "x-scheme-handler/https" = ["firefox.desktop"]; + "x-scheme-handler/about" = ["firefox.desktop"]; + "x-scheme-handler/unknown" = ["firefox.desktop"]; + "application/xhtml+xml" = ["firefox.desktop"]; + "text/xml" = ["firefox.desktop"]; + }; + in + lib.mkIf (config.variables.defaultBrowser == "firefox") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.firefox.enable = true; + + programs.firefox.nativeMessagingHosts = with pkgs; [fx-cast-bridge]; + + programs.firefox.profiles."${username}" = { + extensions = import ./extensions.nix {inherit pkgs;}; + + search = { + force = true; + default = "Ecosia"; + engines = import ./searchEngines.nix {inherit lib pkgs;}; + }; + + settings = { + "widget.use-xdg-desktop-portal.file-picker" = 1; + "browser.disableResetPrompt" = true; + "browser.download.panel.shown" = true; + "browser.download.useDownloadDir" = true; + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; + "browser.shell.checkDefaultBrowser" = true; + "browser.shell.defaultBrowserCheckCount" = 1; + "browser.startup.homepage" = "https://google.com"; + "browser.bookmarks.showMobileBookmarks" = true; + "dom.security.https_only_mode" = true; + "identity.fxaccounts.enabled" = true; + "privacy.trackingprotection.enabled" = true; + "signon.rememberSignons" = false; + "browser.newtabpage.pinned" = lib.singleton { + title = "NixOS"; + url = "https://nixos.org"; + }; + "browser.uiCustomization.state" = '' {"placements":{"widget-overflow-fixed-list":[],"unified-extensions-area":["privacy_privacy_com-browser-action","enhancerforyoutube_maximerf_addons_mozilla_org-browser-action","jid1-93cwpmrbvpjrqa_jetpack-browser-action","sponsorblocker_ajay_app-browser-action","_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action","_25cddbee-458b-4e9f-984d-dbf35511f124_-browser-action","canvasblocker_kkapsner_de-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_74145f27-f039-47ce-a470-a662b129930a_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_cb31ec5d-c49a-4e5a-b240-16c767444f62_-browser-action"],"nav-bar":["back-button","forward-button","stop-reload-button","home-button","firefox-view-button","urlbar-container","fxa-toolbar-menu-button","downloads-button","library-button","keepassxc-browser_keepassxc_org-browser-action","ublock0_raymondhill_net-browser-action","addon_darkreader_org-browser-action","plasma-browser-integration_kde_org-browser-action","_testpilot-containers-browser-action","unified-extensions-button","reset-pbm-toolbar-button","_3c078156-979c-498b-8990-85f7987dd929_-browser-action","browserpass_maximbaz_com-browser-action"],"toolbar-menubar":["menubar-items"],"TabsToolbar":["tabbrowser-tabs","new-tab-button","alltabs-button"],"PersonalToolbar":["import-button","personal-bookmarks"]},"seen":["save-to-pocket-button","developer-button","ublock0_raymondhill_net-browser-action","_testpilot-containers-browser-action","privacy_privacy_com-browser-action","addon_darkreader_org-browser-action","enhancerforyoutube_maximerf_addons_mozilla_org-browser-action","jid1-93cwpmrbvpjrqa_jetpack-browser-action","keepassxc-browser_keepassxc_org-browser-action","plasma-browser-integration_kde_org-browser-action","sponsorblocker_ajay_app-browser-action","_762f9885-5a13-4abd-9c77-433dcd38b8fd_-browser-action","browserpass_maximbaz_com-browser-action","_25cddbee-458b-4e9f-984d-dbf35511f124_-browser-action","canvasblocker_kkapsner_de-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_3c078156-979c-498b-8990-85f7987dd929_-browser-action","_74145f27-f039-47ce-a470-a662b129930a_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_cb31ec5d-c49a-4e5a-b240-16c767444f62_-browser-action"],"dirtyAreaCache":["nav-bar","PersonalToolbar","toolbar-menubar","TabsToolbar","widget-overflow-fixed-list","unified-extensions-area"],"currentVersion":20,"newElementCount":7} + ''; + }; + }; +} + +``` + +Contents of modules/home/firefox/floorp.nix: +``` +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "floorp" { + xdg.mimeApps = let + defaultApplications = { + "default-web-browser" = ["floorp.desktop"]; + "text/html" = ["floorp.desktop"]; + "x-scheme-handler/http" = ["floorp.desktop"]; + "x-scheme-handler/https" = ["floorp.desktop"]; + "x-scheme-handler/about" = ["floorp.desktop"]; + "x-scheme-handler/unknown" = ["floorp.desktop"]; + "application/xhtml+xml" = ["floorp.desktop"]; + "text/xml" = ["floorp.desktop"]; + }; + in + lib.mkIf (config.variables.defaultBrowser == "floorp") { + enable = true; + inherit defaultApplications; + associations.added = defaultApplications; + }; + + programs.floorp.enable = true; + + programs.floorp.nativeMessagingHosts = with pkgs; [fx-cast-bridge kdePackages.plasma-browser-integration]; + + programs.floorp.profiles."${username}" = { + extensions = import ./extensions.nix {inherit pkgs;}; + + search = { + force = true; + default = "Ecosia"; + engines = import ./searchEngines.nix {inherit lib pkgs;}; + }; + }; +} + +``` + +Contents of modules/home/firefox/default.nix: +``` +_: { + imports = [ + ./firefox.nix + ./floorp.nix + ./zen.nix + ]; +} + +``` + +Contents of modules/home/firefox/searchEngines.nix: +``` +{ + lib, + pkgs, + ... +}: let + nix-icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; +in { + "Ecosia" = { + iconUpdateURL = "https://www.ecosia.org/static/icons/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; # Every day + definedAliases = ["@e" "@ecosia"]; + urls = lib.singleton {template = "https://www.ecosia.org/search?q={searchTerms}";}; + }; + + "Nix Packages" = { + inherit nix-icon; + definedAliases = lib.singleton "@np"; + urls = lib.singleton {template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}; + }; + + "NixOS Options" = { + inherit nix-icon; + definedAliases = lib.singleton "@no"; + urls = lib.singleton {template = "https://search.nixos.org/options?type=packages&query={searchTerms}";}; + }; + + "NixOS Wiki" = { + inherit nix-icon; + definedAliases = lib.singleton "@nw"; + urls = lib.singleton {template = "https://wiki.nixos.org/w/index.php?search={searchTerms}";}; + }; + + "Nixpkgs PR Tracker" = { + inherit nix-icon; + definedAliases = ["@nprt"]; + urls = lib.singleton {template = "https://nixpk.gs/pr-tracker.html?pr={searchTerms}";}; + }; + + # All these after all from llakala + "Noogle" = { + inherit nix-icon; + definedAliases = ["@nog"]; + urls = lib.singleton {template = "https://noogle.dev/q?term={searchTerms}";}; + }; + + "Nixpkgs" = { + iconUpdateURL = "https://github.com/favicon.ico"; + definedAliases = ["@npkgs"]; + urls = lib.singleton { + template = "https://github.com/search"; + # Thanks to xunuwu on github for being a reference to use of these functions + params = lib.attrsToList { + "type" = "code"; + "q" = "repo:NixOS/nixpkgs lang:nix {searchTerms}"; + }; + }; + }; + + "Github Nix Code" = { + iconUpdateURL = "https://github.com/favicon.ico"; + definedAliases = ["@ghn"]; + urls = lib.singleton { + template = "https://github.com/search"; + # Thanks to xunuwu on github for being a reference to use of these functions + params = lib.attrsToList { + "type" = "code"; + "q" = "lang:nix NOT is:fork {searchTerms}"; + }; + }; + }; +} + +``` + +Contents of modules/home/development/python.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "python" { + programs.pyenv.enable = true; + + home.sessionVariables.PYENV_ROOT = "${config.xdg.dataHome}/pyenv"; + + home.sessionPath = ["${config.home.sessionVariables.PYENV_ROOT}/bin"]; + + home.packages = with pkgs; let + myPythonPackages = ps: + with ps; [ + debugpy + pyflakes + isort + pytest + black + pip + pipx + ]; + in [ + # :lang python, debugger, formatter + (python312.withPackages myPythonPackages) + pyright + pipenv + ]; +} + +``` + +Contents of modules/home/development/lua.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "lua" { + home.packages = with pkgs; [ + # :editor format + nodePackages.lua-fmt + # :tools lsp :lang lua + lua-language-server + ]; +} + +``` + +Contents of modules/home/development/java.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "java" { + programs.java.enable = true; + + home.sessionVariables.JDTLS_PATH = "${pkgs.jdt-language-server}/share/java"; + + home.packages = with pkgs; [ + # :tools lsp + java-language-server + + # :lang java + jdt-language-server + ]; +} + +``` + +Contents of modules/home/development/nix.nix: +``` +{ + config, + lib, + pkgs, + ... +}: let + alejandra-quiet = pkgs.writeShellScriptBin "alejandra-quiet" ''alejandra --quiet "$@"''; +in + lib.utilMods.mkModule config "nix" { + programs.nix-index-database.comma.enable = true; + + home.packages = with pkgs; [ + nh # Nice wrapper for NixOS and HM + alejandra # Nix formatter + nix-output-monitor # Monitor Nix compilation + nvd # Nix/NixOS package version diff tool + nixpkgs-review # Review nixpkgs + nurl # Automated prefetch tool for + nix-init # Automatically create nix packages from URLs + nix-inspect # View nix configurations + nil # Nix LSP + deadnix # Deadcode finder for NIx + statix # Anti-pattern detector + + alejandra-quiet # Wrapper for Emacs + ]; + } + +``` + +Contents of modules/home/development/markdown.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "markdown" { + home.packages = with pkgs; [ + # :lang markdown + proselint + pandoc + grip + ]; +} + +``` + +Contents of modules/home/development/c.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "c" { + home.packages = with pkgs; [ + # :editor format + clang-tools + # :tools lsp + omnisharp-roslyn + gcc + ]; +} + +``` + +Contents of modules/home/development/rust.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "rust" { + home.packages = with pkgs; [rustup]; +} + +``` + +Contents of modules/home/development/latex.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "latex" { + home.packages = with pkgs; [ + # :editor format + texlive.combined.scheme-medium #LaTex + ]; +} + +``` + +Contents of modules/home/development/web.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "web" { + home.packages = with pkgs; [ + # :editor format + html-tidy + + # :lang web + stylelint + jsbeautifier + ]; +} + +``` + +Contents of modules/home/development/_default.nix: +``` +{ config, pkgs, ... }: + +{ + imports = [ + ./env + ./languages + ./tools + ]; +} + +``` + +Contents of modules/home/development/_env/_versions.nix: +``` +{ config, pkgs, ... }: + +{ + home.sessionVariables = { + PYTHON_VERSION = "3.11"; + NODE_VERSION = "20"; + GO_VERSION = "1.21"; + RUST_VERSION = "stable"; + }; +} + +``` + +Contents of modules/home/development/_env/_paths.nix: +``` +# users/jeirmeister/programs/development/env/common/paths.nix +{ config, pkgs, ... }: + +{ + home.sessionVariables = { + # Tool-specific paths + DEVELOPMENT_TOOLS_HOME = "${config.xdg.dataHome}/dev-tools"; + VIRTUALENV_HOME = "${config.xdg.dataHome}/virtualenvs"; + NODE_PACKAGES_DIR = "${config.xdg.dataHome}/node-packages"; + CARGO_HOME = "${config.xdg.dataHome}/cargo"; + GO_PATH = "${config.xdg.dataHome}/go"; + }; + + # Ensure directories exist + home.file = { + "${config.xdg.dataHome}/dev-tools/.keep".text = ""; + "${config.xdg.dataHome}/virtualenvs/.keep".text = ""; + "${config.xdg.dataHome}/node-packages/.keep".text = ""; + # Add standard cache directories + "${config.xdg.cacheHome}/yarn/.keep".text = ""; + "${config.xdg.cacheHome}/pnpm/.keep".text = ""; + + # Add standard data directories + "${config.xdg.dataHome}/node/.keep".text = ""; + "${config.xdg.dataHome}/python/.keep".text = ""; + "${config.xdg.dataHome}/cargo/.keep".text = ""; + }; + + # Add to env/common/paths.nix + home.sessionPath = [ + "$HOME/.local/bin" + "${config.home.sessionVariables.CARGO_HOME}/bin" + "${config.home.sessionVariables.GO_PATH}/bin" + "${config.home.sessionVariables.NODE_PACKAGES_DIR}/bin" + ]; + + assertions = [ + { + assertion = config.xdg.enable; + message = "XDG Base Directory support must be enabled"; + } + ]; +} + +``` + +Contents of modules/home/development/_env/_default.nix: +``` +{ config, pkgs, ... }: + +{ + imports = [ + ./paths.nix + ./versions.nix + ]; +} + +``` + +Contents of modules/home/development/_languages/_javascript.nix: +``` +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + nodePackages.npm + nodePackages.node-gyp + nodePackages.node-pre-gyp + nodePackages.pnpm + yarn + ]; + + home.file.".npmrc".text = '' + prefix=${config.home.sessionVariables.NODE_PACKAGES_DIR} + ''; + + + home.file.".pnpmrc".text = '' + pnpm-version=8.9.0 + store-dir=${config.home.sessionVariables.XDG_DATA_HOME}/pnpm + ''; + + + home.file.".yarnrc".text = '' + cache-folder "${config.home.sessionVariables.XDG_CACHE_HOME}/yarn" + ''; +} + +``` + +Contents of modules/home/development/_languages/_go.nix: +``` +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + go + gopls + golangci-lint + delve + ]; + + home.sessionVariables = { + GOPATH = "${config.home.sessionVariables.GO_PATH}"; + GOBIN = "${config.home.sessionVariables.GO_PATH}/bin"; + }; +} + +``` + +Contents of modules/home/development/_languages/_rust.nix: +``` +{ config, pkgs, ... }: + +{ + + home.sessionVariables = { + RUSTUP_HOME = "${config.home.sessionVariables.XDG_DATA_HOME}/rustup"; + }; + + home.packages = with pkgs; [ + cargo-edit + cargo-watch + cargo-audit + cargo-tarpaulin + rustup + ]; + + home.file.".cargo/config.toml".text = '' + [build] + target-dir = "target" + + [cargo-new] + vcs = "git" + ''; + + + home.file.".rustup/settings.toml".text = '' + default_toolchain = "${config.home.sessionVariables.RUST_VERSION}" + profile = "default" + ''; +} + +``` + +Contents of modules/home/development/_languages/_default.nix: +``` + +``` + +Contents of modules/home/development/_languages/_python/_default.nix: +``` +{ config, pkgs, ... }: + +let + pythonVersion = builtins.replaceStrings [ "." ] [ "" ] config.home.sessionVariables.PYTHON_VERSION; + pythonPackages = pkgs."python${pythonVersion}Packages"; + + # import custom packages + repo-to-text = pkgs.callPackage ./repo-to-text.nix { }; + +in +{ + home.sessionVariables = { + PYTHONDONTWRITEBYTECODE = 1; + PYTHONIOENCODING = "UTF-8"; + VIRTUAL_ENV_DISABLE_PROMPT = 1; + }; + + home.packages = with pythonPackages; [ + pip + setuptools + wheel + black + pylint + mypy + pytest + pytest-cov + + # Time tracking + toggl-cli + + # Add other Python CLI tools + httpie # HTTP client + youtube-dl # Video downloader + + # Custom CLI tools + repo-to-text + ]; + +} + +``` + +Contents of modules/home/development/_languages/_python/_packages/_repo-to-text.nix: +``` +{ + lib, + python311Packages, + fetchPypi, + tree, +}: + +python311Packages.buildPythonPackage rec { + pname = "repo_to_text"; + version = "0.4.2"; + format = "setuptools"; + + src = fetchPypi { + pname = "repo_to_text"; + inherit version; + sha256 = "d2oydJFP6PNUyPVZlrOtCkyMrFZyc1fkGRa/ZnqsCkQ="; + }; + + propagatedBuildInputs = with python311Packages; [ + pyyaml + pyperclip + pathspec + ]; + + buildInputs = [ + tree + ]; + + pythonImportsCheck = [ "repo_to_text" ]; + + meta = with lib; { + description = "Convert directory/repository structure and contents into a single text file"; + homepage = "https://github.com/kirill-markin/repo-to-text"; + license = licenses.mit; + maintainers = [ ]; + }; + + postInstall = '' + mv $out/bin/repo_to_text $out/bin/repo-to-text || true + ''; +} + +``` + +Contents of modules/home/development/_tools/_git.nix: +``` +{ + config, + pkgs, + lib, + ... +}: + +{ + programs.git = { + enable = true; + package = pkgs.git; + lfs.enable = true; + userName = "jeirmeister"; + userEmail = "jeir@jeirslab.xyz"; + + # Enable commit and tag signing with specific GPG key + signing = { + key = "0x33A40DF62D35C4A7"; # Your specific key ID + signByDefault = true; + }; + + extraConfig = { + init.defaultBranch = "main"; + pull.rebase = false; + + # GPG program configuration + gpg = { + program = "${pkgs.gnupg}/bin/gpg2"; + format = "openpgp"; + }; + + # Credential configuration + credential = { + helper = lib.mkForce "${pkgs.git-credential-manager}/bin/git-credential-manager"; + credentialStore = "plaintext"; + interactive = false; + }; + + # Enable GPG signing for commits and tags + commit.gpgSign = true; + tag.gpgSign = true; + + safe.directory = "*"; + }; + }; + + xdg.enable = true; +} + +``` + +Contents of modules/home/development/_tools/_direnv.nix: +``` +{ config, pkgs, ... }: + +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + enableZshIntegration = true; + }; +} + +``` + +Contents of modules/home/development/_tools/_default.nix: +``` +{ config, pkgs, ... }: + +{ + imports = [ + ./git.nix + ./direnv.nix + ]; + + home.packages = with pkgs; [ + git + git-credential-manager + gh + gotty + git-crypt + sops + ]; +} + +``` + +Contents of modules/home/comms/discord.nix: +``` +{ + config, + osConfig, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "discord" { + home.packages = with pkgs; + if (lib.conds.isWayland osConfig) + then [discord-wayland vesktop] + else [discord]; + + # make vesktop autostart properly + xdg.configFile."autostart/vesktop.desktop".text = '' + [Desktop Entry] + Type=Application + Version=1.0 + Name=Vencord + Comment=Vencord autostart script + Exec=sh -c "${pkgs.vesktop}/bin/vesktop --start-minimized" + Terminal=false + StartupNotify=false + ''; +} + +``` + +Contents of modules/home/comms/messengers.nix: +``` +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + # Communication + signal-desktop + telegram-desktop + whatsapp-for-linux + + # Productivity + zoom-us + obsidian + bitwarden-desktop + todoist-electron + obs-studio + + ]; +} + +``` + +Contents of modules/home/_editors/_sublime.nix: +``` +{ config, pkgs, ... }: +{ + # Install Sublime Text through home.packages + home.packages = with pkgs; [ + sublime4 # Or sublime3 if you prefer + ]; + + # Sublime settings live in a specific directory + home.file = { + ".config/sublime-text/Packages/User/Preferences.sublime-settings".text = builtins.toJSON { + # Your sublime settings here + font_size = 12; + font_face = "FiraCode Nerd Font"; + theme = "Adaptive.sublime-theme"; + color_scheme = "Packages/Color Scheme - Default/Monokai.sublime-color-scheme"; + ignored_packages = [ "Vintage" ]; + rulers = [ + 80 + 120 + ]; + tab_size = 2; + translate_tabs_to_spaces = true; + ensure_newline_at_eof_on_save = true; + trim_trailing_white_space_on_save = true; + }; + + # Key bindings + ".config/sublime-text/Packages/User/Default (Linux).sublime-keymap".text = builtins.toJSON [ + { + keys = [ "ctrl+shift+f" ]; + command = "reindent"; + } + ]; + + # Package Control settings + ".config/sublime-text/Packages/User/Package Control.sublime-settings".text = builtins.toJSON { + installed_packages = [ + "Package Control" + "SideBarEnhancements" + "A File Icon" + "Dracula Color Scheme" + "GitGutter" + "MarkdownEditing" + ]; + }; + }; +} + +``` + +Contents of modules/home/_editors/_default.nix: +``` +{ config, pkgs, ... }: + +{ + imports = [ + ./sublime.nix + ./vscode + ]; +} + +``` + +Contents of modules/home/_editors/_vscode/_settings.nix: +``` +{ pkgs, ... }: +{ + # Set the default integrated terminal to zsh + "terminal.integrated.shell.linux" = "${pkgs.zsh}/bin/zsh"; + "terminal.integrated.defaultProfile.linux" = "zsh"; + + # Existing settings + "editor.fontSize" = 14; + "editor.fontFamily" = "FiraCode Nerd Font"; + "editor.formatOnSave" = true; + "files.autoSave" = "onWindowChange"; + "workbench.colorTheme" = "Dracula"; + "editor.minimap.enabled" = false; + "editor.rulers" = [ + 80 + 120 + ]; + "files.trimTrailingWhitespace" = true; + "editor.bracketPairColorization.enabled" = true; + + # Git settings (unchanged) + "git.enabled" = true; + "git.autofetch" = true; + "git.confirmSync" = false; + "git.enableSmartCommit" = true; + "git.path" = "${pkgs.git}/bin/git"; + "git.openRepositoryInParentFolders" = "never"; + + # GitLens settings (unchanged) + "gitlens.hovers.currentLine.over" = "line"; + "gitlens.currentLine.enabled" = true; + "gitlens.hovers.enabled" = true; + "gitlens.mode.active" = "zen"; + + # Credential manager integration (unchanged) + "git.terminalAuthentication" = true; + "git.credential.helper" = "${pkgs.git-credential-manager}/bin/git-credential-manager"; + + # Nix configuration + "nix.enableLanguageServer" = true; + "nix.serverPath" = "nil"; + "nix.serverSettings" = { + "nil" = { + "formatting" = { + "command" = [ "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt" ]; + }; + }; + }; + "[nix]" = { + "editor.defaultFormatter" = "jnoortheen.nix-ide"; + "editor.formatOnSave" = true; + }; + +} + +``` + +Contents of modules/home/_editors/_vscode/_extensions.nix: +``` +{ pkgs, ... }: +with pkgs.vscode-extensions; +[ + ms-vsliveshare.vsliveshare + ms-python.python + rust-lang.rust-analyzer + ms-azuretools.vscode-docker + pkief.material-icon-theme + dracula-theme.theme-dracula + jnoortheen.nix-ide +] + +``` + +Contents of modules/home/_editors/_vscode/_default.nix: +``` +{ config, pkgs, ... }: + +let + userSettings = import ./settings.nix { inherit pkgs; }; + extensions = import ./extensions.nix { inherit pkgs; }; +in +{ + programs.vscode = { + enable = true; + extensions = extensions; + userSettings = userSettings; + }; + + # Your other configurations like home.packages etc. + home.packages = with pkgs; [ + nixpkgs-fmt + nil + ]; +} + +``` + +Contents of modules/home/virtualization/virtualization.nix: +``` +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "virtualization" { + # Enable dconf (System Management Tool) + #programs.dconf.enable = true; + + # Install necessary packages + environment.systemPackages = with pkgs; [ + virt-manager + virt-viewer + #spice + #spice-gtk + #spice-protocol + win-virtio + win-spice + guestfs-tools + libguestfs + ]; + + # Manage the virutalisation services + virtualisation.spiceUSBRedirection.enable = true; + virtualisation.libvirtd = { + enable = true; + qemu.swtpm.enable = true; + qemu.ovmf = { + enable = true; + packages = with pkgs; [OVMFFull.fd]; + }; + }; + + services.spice-vdagentd.enable = true; +} + +``` + +Contents of modules/home/virtualization/waydroid.nix: +``` +{ + pkgs, + lib, + config, + ... +}: +lib.utilMods.mkModule config "waydroid" { + virtualisation.waydroid.enable = true; + environment.systemPackages = with pkgs; [nur.repos.ataraxiasjel.waydroid-script]; +} + +``` + diff --git a/secrets/default.nix b/secrets/default.nix index e69de29..e62b7fd 100644 --- a/secrets/default.nix +++ b/secrets/default.nix @@ -0,0 +1,34 @@ +{ config, pkgs, lib, ... }: + +{ + imports = [ + ./users + ]; + + options = { + variables.secrets = { + identityPaths = lib.mkOption { + type = lib.types.listOf lib.types.path; + default = [ ]; + description = "List of paths to age identities for secret decryption"; + }; + + userKeys = lib.mkOption { + type = lib.types.attrsOf (lib.types.listOf lib.types.str); + default = { + jeirmeister = [ + "0x33A40DF62D35C4A7" # Your GPG key ID + ]; + }; + description = "User GPG keys for secret encryption"; + }; + }; + }; + + config = { + age = { + identityPaths = config.variables.secrets.identityPaths; + secrets = import ./secrets.nix { inherit config pkgs lib; }; + }; + }; +} diff --git a/secrets/keys/gpg/private.key b/secrets/keys/gpg/private.key deleted file mode 100644 index 774f291e391bc4e5172609c320fab8238f659c9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4971 zcmV-x6O`-#M@dveQdv+`03CPYh_tY-)e?pZpMM!zwS~hi{F=gK*WRYN(_h~17XQo5 zCQ=JTqg|3XongxaF9)e#0UY|QDWGdXzRg;$-E1cCM*f<1CsbD=ZOe@jqU?;fF2%7_ z#Zb!tJoRRBoHStwvbaH;2fPVKHYL)_Mk)o7MJvU&JnZJ6e)ICC!UDKQHKGH2>)cnm z&qpmRhG=>93}j#U0*c6h7?jLQUm@fj&dxRy*&K&3?vUH9>{{!Sw_c$jbJ01G3%;}~ zs+}$F^DChZ&F)l|#R&vw>byuioMU+P=8lL#HpI8E?`c32O`k$d9M@_gQ6@Si`Tj;| zLlxE}v%S+#==!c=b9wz(qL> zqE~5f;KxEjlwM#8t%`pStvb0ZQ8>UL4Cw>BUd^`u{bGT}*T!RLxhF z9~a{I*J{T0lP&uLb1GaP5^@A@-U2;R*y~8SB#h}Vn{_PlKRY9y|jg_xx8Sk*Ksch5t zQYmsxfgjy%ePF(Og0Ro!jM?aQgNgOAKB!)1@ukL>AWrr-$xC#&gPXmRu#OI)a7q!= zW(X6=DD=9rJ0p>qbNC#YOQ;)4u!7Q%!;=oRW=0OoP+Fs%Vks4*{T6l0OZI|A-svgU z+B$^L^CqS8>w2swW=FYGzsr6c`4GECE*&qOOtieM@h?O_;10t*mHxm>kBB{X9~P&Y zY|ft?H<8GXo6+?A2E$Tf@PlGUa&oY+a_LrNDu2yJ% zna)ae>bpMA{>s|eBZK(y<$k-6bwkY{M}aORQw16{)eSUrQZunO2i6H811`2M>L_)m zMr{-<1&<%u<~!b(i6JYVx$ry+VP~C3hSOY!lgE(wrcq%@vYM9k%@bL~S0Nvw<~jyU zAtQ9;m4ev$X6R9Qimj8(Nx+t2bYJ6#Bmz^f+gI2~2@L0Tk%Xd3qarTbg1H|X+9Enf z6lBJuB+r@fO3X-HW=vJjbf zF6oi_8|YXnmD_<=U9BNQ>gmue67l(GmnYQcHL1n^XK#LD>v2%>+h4~&_*TcI+!Z9& zRx{Bo#|b4^r!UT@>P6d_UPVzk~147nSHW$iEK8b=H_;y!5ly$M;tnIgd)+q ze@aukqF{fT5fE);v>ABgTStUG`O|SZ2+%UL9f>2^QAR_vcRY{ghno|e+JzbXdgjfD z8346Jd4L=@6=m>lo#2XWN=>j|b>6x3-RJaCSC`G>H^a zaw<-GxdUZEClNQuKA1B*G6TWwS_(Z9Zx7K2!cJo;$_D=qtzXdBLwFq&MT0F5Hnb~? zaiL*LIzP7%DVjv3rlc%cv|&^w!7?J@+PMpgM``ZJZc)XE$AF$bYQUfCvxvdd&iAb@ zI>ADD$P@?`p8HEHNq7(OZIwz9`&~yG)PT5<7sC*S)Qd+5e}XL5LWlV=JKVy;IW$~k z=M$o&9?>hz>Zy}LH=&0ARZTs|f!FCLRYV6U8=hTxbnm&uQPW!t~DkrCSD{_wYc?_(WtSS`UYhLeGQsja7Cf$ci zG1pW3v-s-Y$nnpOpOwtHa&s9Pq_29E9-RtE-Pe**LV9hTdo&W#0l=GT$i0c1<9Sj4 z4$!!mFqR1zW?0o`Z``;OWV9!*&Dxj0rId07E0XIFFo=_$Exr=L7pGx*tMURi5k=4E zdBjtCZ14|#l@s^r4MS`IC;m|)Z07Ype&m#rbONn?zw)I|&=Ll}mr zOQafO$*ML+Ru*k(G_AnLfe`z%(;<{N%sYAn`+S zd7nQia<#$|WwOGG9#v?C_oB%g2A-|3eyaPcihN3`O)e_JsXWy2UMX)#=~gx4FdMPM zecL+YV3=uUxgSY0gTa!0TY0Yi?a$eV=a!NZRklVBOA~4Zx?|3Cnx&gc0&;EicIKS{ zTTFvOvwa6jH`Z@R_XW<-fx!!RxNVX`H*VFfAM1RY7+UQ*zC}#CG|Q+LOgGN*APeXb z!hQeaj2?dky6VH45JSW2D#)E=)&d6gtg)CXv$_4!J;uBn9gTNn+N|Ln~Ot=iDSRpC6EtrD9FP%w!gB30nUW4+O4MUaD&abc` zUG^he=j?lhv4s45v?N%Xa#ICJweliGvu{H)3ll1oiAQ{>RrTb=SVBoLTp8EA3F(%N z)Tt_jhFQOyFMIcu8RNpM{Ph1 zerg}$M{x@sbN@KhbQ<~~uX|bngU`xp7FsC$MtCch(*k)6$a|NLhz_BnHuTzAQ$oAj zZLsR3wi8Rk;S|VNAC~|`mf8)B%}aVXmcVteh59iMKWhO9oe!}*CUX^4@L+rue8OU( zzyMHzbq}GuC+pa$BaB9OEQ~Q|Px~@Sa+$BVgZh-wt&Mt3(Cksyseq-lu27l^m0`<&%6x)^Y>Xro813p?okxI?{ zk|di}pcEOc48Z5hc|!io`bIE6@d7dju)|IO1+y^iaTJyHb1M^dRBO;Fg{qr^#7)8? zu&!E%DWbz-%684nlu-_Ah^8W}TkG`X>8&3A#GPu-H={HL=$t!eUCYQ34nk3CVv;__Fo;5J5Wa3VofZO1_+1{iQGxy<2yu2ZUGBN>Bq*186Le)tw#98CdV zsOS4{g94pL++mX~$99LMi}x)H_aSL^(v}Hbp=Eu3)H88?KN#tyM!rms%;NifEZ9nn(-c`J-MC_ zy2KRo7vm5cmeD#1uH?Vn7o`6vht%IP&n~RP;lWVp0CnrU5lE!+tA@2gWbd3w=8~+^ zS$Ed}B->e+pDrhb1h|IRR3>zjRPe@ibMHS(oY^K^Y;JGDS#TcFITSC^lCo^EcXEW< ztGL&7=bTRHf0cU|^;v~fs@}O<%`fj}FCUOqj_9foxkYRPUMncHJL4s&tK!BZpWgp{ z@qfjS)9VI!;wU6^m|K%;S%ow%n@>6!mv=G^>6a!~8IS0TiIBbweBjLm>@OKWecHKO_V znqwe=5>2zY9tZVaz&gso1n;zSN^|?l=u*Y%PDbMMO@FtpVyNC8iOII)@ybWZo|Vj| z?{$)Wym&Bkm;=5EqUT6MtXh0cBX5eUVO-v z09?bOK6h+KoWlXFdt_0|zZUHkG?xJAUG4{#pnN<C!0l_t1%*v|FWmNUDeeN3Z zIKX~21mvm7XaIX24cyeSET~VbIuJL|VEBFn^*&sb_@|xEn)GmJL3{kQC__knr>2MJ zo)+wLq(D>HNDS)=aXU{_7#KEYBkWnl*4O$`hloe|=5>Y(Et=vHGI}Y9?wVm+glNO9 z=CJoWJ2u}Frj)_&o+)p)bv^6u_IOUjNCaVH6wmjnI&zGTlTq7$%U7LQM!U#}MuIXP zV29ASbknZT+rI_u4}I>*Ce@5`8N5fSZrkG&kse2>|D+h@LgFmaZUmpwDd=i>mr$PH z>_l}6Dz@C;UU&Ns>lK3yUTkBn(p^N;@1Nw~TY%^P{Hm+v@SNo#0>=L!QfZ=A)Dd2z z1LpGh8yr`2oIMJ$%=~oOERyq)_e2}J1%TBdgn8f1o5RDNd z?}7})*;f?uIQxg935j+Dpt{@V&fIL1NE2}T>x|#*09khLIDboaPWJ3V^Y}o z+cqNA5QW$HID)j#)X34sht7DC;1dr|ybq>(lrmPOOVG;38FHhx4*L>|-MZWTEku_l zv6I%BunPD}a4M#%et_hWci3(>BKbf;yk_+G`t_@5RvZ=decLoqCEYKLyu>$q zu+C2H^JLLbdX}w*M6wJQ)h+tl1>FmjAZRX zh@aT@e5#PoTQqx+N1Y%pXTw6~5*qzM$g7$Zq*y=jv$TJ4R0P&f5`5u3Ac=0*yO#cY pO@buFuypPC=xV2tT2y#ti1V-L2;1_?Q2t1B7hv>5f?H28b90qGslEUJ diff --git a/secrets/keys/ssh/id_ed25519 b/secrets/keys/ssh/id_ed25519 deleted file mode 100644 index 458a0e9f8cd6983845ab0da6e2711ca4508f8833..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 433 zcmV;i0Z#q^M@dveQdv+`0IH;XZY5jZtbZs97;ki{IOgb4*6i-OZpG>#BC6Bjok~Qt z#`y=Qbf)tf8e}a@VbPR-`E9`w-S$yOT?a~_wa;9;JqUeehf@h@z>EyI)|DzBtPD-B zWlu5yudkK0mm{nVw=Ud6WIh}pZtuMzIpIECDg2t1!f^`ZkbUdUMXIUbZ}aFdfvS;L zn}k>DgEY=ZB+8bqF3C%;wmV?@9#U29e=FYdQ3Ud1ioQGOvi-(7xhkFRO%OMB$%jLm zlYCD+8}%T?f4?^)9U~q^>wVZc@siF=-dFAcY+pjx+p+@=hngIk!R0l*;D;FAwMI+- zrO~qkc&KO@!hQ^G-!N#pDG)z|umW9d#`RA$?O!UvbODp)YD>e4q2f3$`315?q$X<* z-bcPm;eD3hJ#llA=ak^zRh;#N+ZuRbhT?t3I-wLkw5@ADvi9iHLKLg;zc;GD4$8hb z>cKLtPV)Xc#l<7fIR4U&kU300C|Ip>BnR7mnnEXkYPa38SNr##|>yL^eog9fdZ!eisNz%v(Mcx*f z3UjnNMA2~m?2?A`rz+h_GoNa^im>AHSfgbP={vtu0{t>3fAvGdwK&5km~YGbON;*e;M`}@JSh8`UA4I*OBx19btNqusr|(8u~JOnLtFx&R=NJ?b_OL!JSJ)@b@?0jiO;Rp zB6hi6c{X*0g%XqgqnYnvU%G;Mxc16YOb?N*5w?cJM|>PFnv~&}f%SjGO(p0P7hyRE z@h1@r!as@L%ZDfti>Y%fYC?ZPHWuo-dOqDfmSYnCP4u%Q`DpxPiDA>mUpXc|lYsdu z(^ceh3rcp+?symC1t10jfX|qyD3-{^=*ApDf06dbm|VDett7vu(t0Ty+wUWo1nvDVHL3KZfrPYnlG8u(X-{Hk>Lat3i= zgUX19DtXP?uo{T+by4G6p}FgKN+8h2g%8)1PL+-B>tfWo%)Rh|CnPcb%=}ud_2{BX zx2M${Z$9nVBj$a&3qr#Ga9f{+Nj=kNy^Ln9xtztf#!CNn8jEBlh43nkf<(X0+%*ex zGW~*M)9M%uusK@z(Ux-h?J1d9v^tLq**bHXV}`%+kM0^e`>COrpcV9``gsouM3>~t zin1#US<#R+0@opEmCOAQ#Ov64UM0f{P%LjgO8ivDB_c6)+mfYV#4Ht*e)*8TbMTKT zKMoYHod7~|6rnJxKB^Vht3G2~#Fg^^UpBI3A-e@jq3Rjm4Y^(N)>dFw`|k@Yc}tt- z4@GvNl5EjS;S9ua<^|ufcVzWs|8)Fv_|}GZIwA_C&j)kxOOI>p_P2`ulS`qQOGxVj z&ex6R98|bxtw$CNVK)FKyl|ZV!V_11mvsp#XH4_mk-%o^uW-Lr8LF6db#+1LrHd{- z#w;dnriSXw%f~AHDR1qx?Q?N&)*hC z(YSO*w{A5wX&K?<$o$wEWSTof!J&kX+jcDC&QK#4EVlD*RN}RjWYiUdpJGB8BLO52 zdEjbQp_;Gs(!+&mukXQ|e?{yGi?i1tGHB&-{{gQu{Mad2RB$SoM02 z;|14bO7qlY{Ri65WPcMc{V>^VI^@%+dAn;9tX zVMqkfGE9fF$r?df1*Zv!E)Q1~t*HQ9XU;Wxb%iH&U`f8?$tfpUSjrl=MPx5GBZa*l zajyac2JzTZ9;G^GS{PRaojkkoD}Vj1d+6&o3n78XWkG784)I7x|F5*XrjKv{WfG29 zPJ^($m7S}jm7SZrl`9iSK|_H_#mbAx+S!%K(Zj*rj@!e{ijztFKauo*#?8UZoad{T zw`3HG8X74O2OvVhjOOe*3oLIUCwO%=B+p-jf5R=HCxe-20oeS1)66OsmVbkQ10{{OVHo_wC(>#t$d9 zRH>K#IGPQDca}N%ovRO2+3oBy%5z#;3|G$!on&VvLaio4D-{&r@5yX5r^p~esrUnW zMmlBcbtuZy$eU-G?7A$0>VA9p+bs$X47H8-R0Y<77|pnsUQMNBfEhWLJ*;AqmYAny z83RZEtORn-@NTj8J&5)1ImjMSMqm+jE|B0hy({}Afd9`=4vy<^Uyienp`21x=`1hq ztd-Rjw`G!QdaaUZHJ^qE=EFq!yhN3u289+HR$}RbtVgQ^=SH@e!}dV*KVuM2NM`h) z?(p8MG?oRGnPI^Bi{VZ{1H)*@6UO59UP_(pw~72OC2k27vM;crmS*bGji&b8Fc`P~ z)K`|A`LR4Dyvn_kqk43-d-!q|p|rA8@jo8~**Q=X{%0gWY-*_{#4Z~T(d?~A48pf7 zepbINAO{ak#r?G5xoa6DjI%wk-Wu>>^p2mDuo5iq%y7;%bl~@nh=q+<<9ZzDu8HQx zl$ssfBv93E9}^TKQ3U|m|3kWL5=#U%Y=Ms2>Ow#by0BuSzMP*)c$1=xQ!sk_gazC! zQ#~x8ZnE8cgo_9H)+TL&HFP}sV*FH?ZBLh0`|X=Hx6RLWT4HS+lR2K2xd$e0bRLG4 zlHP(@TDwPRbS@jY-N?>E{*Fk}2fSJ^-=c92lM;C>G%y>C*pv;vlEy6{zeGc1(vt7B zs(T*Rbs3)W)~`;RlxjYD4)F;P()G+7Ohu^v)~Cj{Te&6V?1FOXVr&l#D8djvtB!I; zOt>BzSFYrX0UX?aWd4Al%2M~zlLtmXvIuVG0EHdD1wmboA-Y)!OI05IwcpEM zwDq6Gg!496OaqMOhFE|0wnpACX4lVXf}^K`aGOax&@OoKqJ1SLB+}ya-l+$k%sZms;F|mFz5-+n$1>XKu0|pUP^iT?BtBrB-kP`Y&qF1uf;zcWI zM`F{`0YB021pYC7BT_{uCeawMZtAn5|0O$aZqU=Hj?2LW+pbewoQq zi~@QwHGFQ(DJc@HYpf2N!*z+HJMv7Rg*toTZC3ngUG| zOCSb4r<=!Jq{(7QeDhBEZiX{(V*VUZ7Yo?}2svaOvzWRo_ z_^flOg_AKgG03_@muX3wJDRsl8_MlwO5(f%KBUhXB<=REjF$3A6BJNE&DM{aNva>a zS}^Q=ygi;Ph6;D0&=8;C^6xqL^@U)x??OhUqvBL`r0#E2Q~2;_#3nYE|AT|B1B>6&S+_@rxDvE_@QrdQ-HKwbLUpL02D6`?*6swWLbCq zD3H5a`n_ZY_EKwMQPoR!^8Fe~q*GfB3wwp-)^xwkP))gCu9!(=!CUUw-ca~}>DD@H zGSQ*^YPSv4yNUjAPXXz0RBNsVZbj%@(V7jvjwqYY1phde56>hr5>87SJk@V0Zyk&@ zP8MzPFd&7cpgHvFwYZ^L#$z=UGpbu{*A((|t z4(rT$>IL_L9XD+NGH7iBi*c?B_2D{v8tjY|5f1hyM(@4hz;tm3Mtfq{W1&H(3rI$X zDl;cZL*-iXLhg}pn;t59^3>}NjK}d4?_I&% z48(C!W)2qp%Gvvje5o&gCRdWSE*(u^69i)`xm+XdU7(B@MGT`@SBi`mO@5{m7J_D( zN~nhMHernYCDq*~XK^yI(3nMwqkJR!hZ_zqmmYq<5j9Lbjw+B!zOU6a_=lUAe(aWj zS*rM%%xVK4OhJGjyugxGL46Dnd`)}wwRnlx(^0od_{?0yqmxGn1-0#v%^`lt*8vB9 zm3Kl@z0tkdG26a6z5V!3PeZcJr^A)Tyy2Fv_*vzJ#kR7d>lrX57dj=)n$J!AxL$Tj z0Ts()bS~}h6jBoL^^bhegy6&u)SkBMi<~ttZuoy(%uILsi9P*FlIk<%3GONj?wXYa zi`3E6MpdSCABX{KTsTtK>f->`b9FGG)4@c^q`LKDbaZZ5_|?+&3`c4yXPe1#{Y&hM ziGo*Bc=}|Nz`9iBy{T2n4NOHW{|`lAPG29hudm~xFRuspr>=E@?|H#LurI-ZgSwU_ ze*&}1f>}6EVL@J0J3z2Q+b{Gqhsw7+8-l%wMMe2Wl=2HQtcOKPpq`c|vu8^>qz0$i z%8wtT3PoRnML%fjTXhem0PsPLAJ&}Oo-8~lYH{?UC#fJIal+q`TzqMB; z>r$l;b$>Iv_u@&i+ntWcpg32@@utHcBfQ+*>!+BcYRb|Y^Y!Jc>U>7!U-G0D5(C!J z%oeXJD}h};Bg^DSdRReDdb0VOoFNKjP}g{CFXL1a6BQMDPH*%xkdL)5cdR3VB0(gJ9YnU6pOb!uIK7yd=B{xv-GB5F1c-O&6P3hbgaN{ zRplMK{1Ptr}~vZ;AB$4twxqM+*`Yg(8GT_5WnX z^nb_`3eXLsJU;yyC~YT zOh*k0M|iA+?E{loCd?cGA7<{$Xg!m!;8Uf#b$@v3Os-|@*|=w4 z@(E!Nx(fXPs!ssT7zllg;yyy##sLoT>XI3c%?}+>S0Obk=AG9@Z?v|oX^?! z{PfK1aQC0c$i#Qc&5X`JM2urU$_L+^RQXi7-;g48j(*gk!4nY=nsrEZp@$6xj{$vU zUyvH`6)k1rgekMH2R8Wr1+nfZ_902n&ofe-__WoD&KmD%2!QG?15Un2LBgGxJ8V(L I0!!rn3#3+vOaK4? literal 0 HcmV?d00001 diff --git a/secrets/keys/gpg/public.key b/secrets/users/jeirmeister/_keys/_gpg/_public.key similarity index 100% rename from secrets/keys/gpg/public.key rename to secrets/users/jeirmeister/_keys/_gpg/_public.key diff --git a/secrets/users/jeirmeister/_keys/_ssh/_id_ed25519 b/secrets/users/jeirmeister/_keys/_ssh/_id_ed25519 new file mode 100644 index 0000000..25f49eb --- /dev/null +++ b/secrets/users/jeirmeister/_keys/_ssh/_id_ed25519 @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACD04ZD4g8/TdqC+MqnlSIWHTNMExpPcR9xoxXcb0p7WsAAAAJhsVPSrbFT0 +qwAAAAtzc2gtZWQyNTUxOQAAACD04ZD4g8/TdqC+MqnlSIWHTNMExpPcR9xoxXcb0p7WsA +AAAEDuUdKAVQz7X+5rGyfRO7yardCsauFdRXJ0/gQpIHSIo/ThkPiDz9N2oL4yqeVIhYdM +0wTGk9xH3GjFdxvSntawAAAAEWplaXJtZWlzdGVyQG5peG9zAQIDBA== +-----END OPENSSH PRIVATE KEY----- diff --git a/secrets/keys/ssh/id_ed25519.pub b/secrets/users/jeirmeister/_keys/_ssh/_id_ed25519.pub similarity index 100% rename from secrets/keys/ssh/id_ed25519.pub rename to secrets/users/jeirmeister/_keys/_ssh/_id_ed25519.pub diff --git a/secrets/users/jeirmeister/default.nix b/secrets/users/jeirmeister/default.nix new file mode 100644 index 0000000..b8ceba3 --- /dev/null +++ b/secrets/users/jeirmeister/default.nix @@ -0,0 +1,38 @@ +{ config, lib, ... }: + +let + secrets = config.age.secrets; +in +{ + age.secrets = { + # SSH keys + "jeirmeister/ssh/id_ed25519" = { + file = ../encrypted/jeirmeister/ssh/id_ed25519.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # GPG keys + "jeirmeister/gpg/private" = { + file = ../encrypted/jeirmeister/gpg/private.age; + owner = "jeirmeister"; + group = "users"; + mode = "0600"; + }; + + # System passwords + "jeirmeister/passwd" = { + file = ../encrypted/jeirmeister/passwd.age; + mode = "0440"; + }; + + # Application secrets + "jeirmeister/borg" = { + file = ../encrypted/jeirmeister/borg.age; + owner = "jeirmeister"; + group = "users"; + mode = "0400"; + }; + }; +} diff --git a/secrets/users/jeirmeister/passwords/_bitwarden.age b/secrets/users/jeirmeister/passwords/_bitwarden.age new file mode 100644 index 0000000..e69de29 diff --git a/secrets/users/jeirmeister/passwords/_sudo.age b/secrets/users/jeirmeister/passwords/_sudo.age new file mode 100644 index 0000000..e69de29 diff --git a/secrets/users/jeirmeister/passwords/_tailscale.age b/secrets/users/jeirmeister/passwords/_tailscale.age new file mode 100644 index 0000000..e69de29 diff --git a/system/boot/default.nix b/system/boot/default.nix new file mode 100644 index 0000000..5b2df8a --- /dev/null +++ b/system/boot/default.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./quietboot.nix + ./systemd-boot.nix + ]; +} diff --git a/system/boot/quietboot.nix b/system/boot/quietboot.nix new file mode 100755 index 0000000..7540826 --- /dev/null +++ b/system/boot/quietboot.nix @@ -0,0 +1,16 @@ +{ config, lib, ... }: + +lib.utilMods.mkModule config "quietboot" { + boot = { + plymouth.enable = true; + consoleLogLevel = 0; + loader.timeout = 0; + initrd.verbose = false; + kernelParams = [ "quiet" ]; + }; + + console = { + earlySetup = true; + useXkbConfig = false; + }; +} diff --git a/system/boot/systemd-boot.nix b/system/boot/systemd-boot.nix new file mode 100644 index 0000000..97c64f3 --- /dev/null +++ b/system/boot/systemd-boot.nix @@ -0,0 +1,12 @@ +{ config, lib, ... }: + +lib.utilMods.mkModule config "systemd-boot" { + boot.loader = { + systemd-boot = { + enable = true; + memtest86.enable = true; + configurationLimit = 10; + }; + efi.canTouchEfiVariables = true; + }; +} diff --git a/system/default.nix b/system/default.nix new file mode 100644 index 0000000..37a3eec --- /dev/null +++ b/system/default.nix @@ -0,0 +1,9 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./boot + ./locales + ./shell + ]; +} diff --git a/programs/desktop/plasma/default.nix b/system/desktop/_plasma6.nix similarity index 100% rename from programs/desktop/plasma/default.nix rename to system/desktop/_plasma6.nix diff --git a/system/desktop/appimage.nix b/system/desktop/appimage.nix new file mode 100644 index 0000000..5e5dbce --- /dev/null +++ b/system/desktop/appimage.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "appimage" { + environment.systemPackages = with pkgs; [appimage-run]; + + # Register AppImage files as a binary type to binfmt_misc, allowing them to be invoked directly + boot.binfmt.registrations.appimage = { + wrapInterpreterInShell = false; + interpreter = "${pkgs.appimage-run}/bin/appimage-run"; + recognitionType = "magic"; + offset = 0; + mask = "\\xff\\xff\\xff\\xff\\x00\\x00\\x00\\x00\\xff\\xff\\xff"; + magicOrExtension = "\\x7fELF....AI\\x02"; + }; +} diff --git a/system/desktop/default.nix b/system/desktop/default.nix new file mode 100644 index 0000000..c402e91 --- /dev/null +++ b/system/desktop/default.nix @@ -0,0 +1,8 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + ./appimage.nix + ./plasma6.nix + ]; +} diff --git a/system/desktop/plasma6.nix b/system/desktop/plasma6.nix new file mode 100644 index 0000000..8f9a820 --- /dev/null +++ b/system/desktop/plasma6.nix @@ -0,0 +1,90 @@ +{ + config, + lib, + pkgs, + ... +}: let + hm-config = config.hm; +in + lib.utilMods.mkModule config "plasma6" { + modules.desktop.enable = true; + modules.desktop.x11.enable = lib.mkForce true; + modules.desktop.wayland.enable = lib.mkForce true; + + # Enable the KDE's SDDM. + services.displayManager.sddm = { + enable = true; + autoNumlock = true; + enableHidpi = true; + wayland.enable = true; + }; + + # Enable Desktop Environment + services.desktopManager.plasma6 = { + enable = true; + enableQt5Integration = true; + }; + + environment.plasma6.excludePackages = with pkgs.kdePackages; [elisa]; + + # Enable KDE partition manager + programs.partition-manager.enable = true; + # Enable KDEConnect + programs.kdeconnect.enable = true; + + environment.systemPackages = with pkgs; + [ + # Apps + krename + qalculate-qt + kdiskmark + + # Libraries/Utilities + clinfo # for kinfocenter for OpenCL page + glxinfo # for kinfocenter for OpenGL EGL and GLX page + vulkan-tools # for kinfocenter for Vulkan page + wayland-utils # for kinfocenter for Wayland page + ffmpegthumbnailer # for video thumbnails + linuxquota # for plasma-disks + gnuplot # for krunner to display graphs + ] + ++ (with kdePackages; [ + # Apps + ktorrent + kfind + filelight + skanpage # Scanner + print-manager + plasma-welcome # Welcome screen + plasma-vault + plasma-disks + + # Libraries/Utilities + kdegraphics-thumbnailers + ffmpegthumbs + qtimageformats + packagekit-qt + sddm-kcm # Add KCM for sddm + ]); + + hm = { + xdg.portal = { + enable = true; + configPackages = with pkgs; lib.mkDefault [kdePackages.xdg-desktop-portal-kde]; + extraPortals = with pkgs; [xdg-desktop-portal-gtk]; + }; + + # Enable native messaging host for Firefox/Firefox forks + programs.firefox.nativeMessagingHosts = with pkgs; [kdePackages.plasma-browser-integration]; + + # Makes Plasma Browser Integration work properly for Vivaldi + xdg.configFile."vivaldi/NativeMessagingHosts/org.kde.plasma.browser_integration.json" = lib.mkIf hm-config.programs.vivaldi.enable {source = "${pkgs.kdePackages.plasma-browser-integration}/etc/chromium/native-messaging-hosts/org.kde.plasma.browser_integration.json";}; + + services.kdeconnect.enable = true; + + xdg.mimeApps = { + defaultApplications."x-scheme-handler/tel" = ["org.kde.kdeconnect.handler.desktop"]; + associations.added."x-scheme-handler/tel" = ["org.kde.kdeconnect.handler.desktop"]; + }; + }; + } diff --git a/system/hardware/bluetooth.nix b/system/hardware/bluetooth.nix new file mode 100644 index 0000000..05eb7c3 --- /dev/null +++ b/system/hardware/bluetooth.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "bluetooth" { + hardware.bluetooth.enable = true; + + # Fix controller compatibility + hardware.bluetooth.input.General = { + ClassicBondedOnly = false; + UserspaceHID = false; + }; +} diff --git a/system/hardware/hardware-acceleration.nix b/system/hardware/hardware-acceleration.nix new file mode 100644 index 0000000..82d1303 --- /dev/null +++ b/system/hardware/hardware-acceleration.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "hardware-accel" { + # Make sure to include this so hardware acceloration actually works + environment.sessionVariables.LD_LIBRARY_PATH = lib.mkBefore ["/run/opengl-driver/lib"]; + environment.systemPackages = with pkgs; [ + libva-utils + clinfo + glxinfo + vulkan-tools + vulkan-loader + ]; + + # Enable OpenGL + hardware.graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [libva-utils libvdpau-va-gl vulkan-validation-layers vulkan-loader]; + extraPackages32 = with pkgs; [libva-utils libvdpau-va-gl vulkan-validation-layers vulkan-loader]; + }; +} diff --git a/system/hardware/qmk.nix b/system/hardware/qmk.nix new file mode 100644 index 0000000..00da943 --- /dev/null +++ b/system/hardware/qmk.nix @@ -0,0 +1,11 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "qmk" { + hardware.keyboard.qmk.enable = true; + + environment.systemPackages = with pkgs; [via qmk]; +} diff --git a/system/hardware/rgb.nix b/system/hardware/rgb.nix new file mode 100755 index 0000000..64acfab --- /dev/null +++ b/system/hardware/rgb.nix @@ -0,0 +1,10 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "openrgb" { + services.hardware.openrgb.enable = true; + services.hardware.openrgb.package = pkgs.openrgb-with-all-plugins; +} diff --git a/system/locales/us-english.nix b/system/locales/us-english.nix new file mode 100644 index 0000000..d2ee053 --- /dev/null +++ b/system/locales/us-english.nix @@ -0,0 +1,26 @@ +{ + config, + lib, + ... +}: +# English (US) display language, US English locale. +lib.utilMods.mkModule config "us-english" { + i18n.defaultLocale = lib.mkDefault "en_US.UTF-8"; + console.keyMap = lib.mkDefault "us"; + services.xserver.xkb = { + layout = lib.mkDefault "us"; + variant = lib.mkDefault ""; + }; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; +} diff --git a/system/services/flatpak.nix b/system/services/flatpak.nix new file mode 100755 index 0000000..8634726 --- /dev/null +++ b/system/services/flatpak.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "flatpak" { + # Enable Flatpak + services.flatpak.enable = true; + + # Create folder where all fonts are linked to /run/current-system/sw/share/X11/fonts + fonts.fontDir.enable = true; + + # Automatically configure it + /* + systemd.services.configure-flathub-repo = { + wantedBy = ["multi-user.target"]; + path = [pkgs.flatpak]; + script = '' + flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + ''; + }; + */ + + environment.etc = { + "flatpak/remotes.d/flathub.flatpakrepo".source = pkgs.fetchurl { + url = "https://dl.flathub.org/repo/flathub.flatpakrepo"; + # Let this run once and you will get the hash as an error. + hash = "sha256-M3HdJQ5h2eFjNjAHP+/aFTzUQm9y9K+gwzc64uj+oDo="; + }; + }; +} diff --git a/system/services/printing.nix b/system/services/printing.nix new file mode 100644 index 0000000..2167231 --- /dev/null +++ b/system/services/printing.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + pkgs, + ... +}: let + printers = with pkgs; [hplipWithPlugin cnijfilter2]; +in + lib.utilMods.mkModule config "printing" { + # Address CUPS vulnerability CVE-2024-47076 + systemd.services.cups-browsed.enable = false; + + # Printer Setup + services.printing = { + enable = true; + drivers = printers; + }; + + # Scanner Setup + hardware.sane = { + enable = true; + extraBackends = with pkgs; [sane-airscan] ++ printers; + }; + + # Install installation + environment.systemPackages = printers; + } diff --git a/system/services/sunshine.nix b/system/services/sunshine.nix new file mode 100644 index 0000000..604bdbe --- /dev/null +++ b/system/services/sunshine.nix @@ -0,0 +1,18 @@ +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "sunshine-server" { + services.sunshine = { + enable = true; + autoStart = true; + capSysAdmin = true; + /* + settings = { + sunshine_name = "${config.networking.hostName}"; + }; + */ + openFirewall = true; + }; +} diff --git a/system/services/syncthing.nix b/system/services/syncthing.nix new file mode 100644 index 0000000..41a372f --- /dev/null +++ b/system/services/syncthing.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + pkgs, + username, + ... +}: +lib.utilMods.mkModule config "syncthing" { + services.syncthing = { + user = lib.mkForce username; + enable = true; + dataDir = "/home/${username}/Sync"; + group = "users"; + configDir = "/home/${username}/.config/syncthing"; + openDefaultPorts = true; + }; + + environment.systemPackages = with pkgs; lib.mkIf (lib.conds.runsDesktop config) [syncthingtray-minimal]; +} diff --git a/system/services/tailscale.nix b/system/services/tailscale.nix new file mode 100755 index 0000000..468a3c0 --- /dev/null +++ b/system/services/tailscale.nix @@ -0,0 +1,16 @@ +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "tailscale" { + services.tailscale = { + enable = true; + useRoutingFeatures = lib.mkDefault "client"; + }; + + networking.firewall = { + checkReversePath = "loose"; + allowedUDPPorts = [41641]; # Facilitate firewall punching + }; +} diff --git a/programs/core/shell/aliases.nix b/system/shell/aliases.nix similarity index 100% rename from programs/core/shell/aliases.nix rename to system/shell/aliases.nix diff --git a/system/shell/atuin.nix b/system/shell/atuin.nix new file mode 100644 index 0000000..284ab98 --- /dev/null +++ b/system/shell/atuin.nix @@ -0,0 +1,37 @@ +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "atuin" { + # The much better shell history database + programs.atuin.enable = true; + + programs.atuin.settings = { + auto_sync = true; + sync_frequency = "10m"; + search_mode = "fuzzy"; + inline_height = 16; + keymap_mode = "vim-insert"; + keymap_cursor = { + emacs = "blink-block"; + vim_insert = "blink-bar"; + vim_normal = "steady-block"; + }; + show_preview = true; + enter_accept = true; + history_filter = [ + "^gpg --key-edit" + "^gpg --list-secret-keys" + "^gpg --list-keys" + "^gpg --recipient" + "^gpg --card-edit" + "^git-crypt add-gpg-user" + "^echo" + "-----BEGIN PGP PRIVATE KEY BLOCK-----" + "^rm -rf" + "^pass" + ]; + sync.records = true; + }; +} diff --git a/programs/core/shell/bash.nix b/system/shell/bash.nix similarity index 100% rename from programs/core/shell/bash.nix rename to system/shell/bash.nix diff --git a/system/shell/bat.nix b/system/shell/bat.nix new file mode 100755 index 0000000..3f425b2 --- /dev/null +++ b/system/shell/bat.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "bat" { + # Fancy 'cat' replacement + programs.bat = { + enable = true; + + config.map-syntax = [".ignore:Git Ignore" "*.conf:INI"]; + + extraPackages = with pkgs.bat-extras; [ + batdiff + batgrep + batman + batpipe + prettybat + ]; + }; + + programs.fzf.fileWidgetOptions = lib.mkIf config.programs.fzf.enable (lib.mkBefore ["--preview '${pkgs.bat}/bin/bat -n --color=always {}'"]); +} diff --git a/system/shell/cava.nix b/system/shell/cava.nix new file mode 100644 index 0000000..f646fd5 --- /dev/null +++ b/system/shell/cava.nix @@ -0,0 +1,43 @@ +{ + config, + lib, + ... +}: +lib.utilMods.mkModule config "cava" { + # CLI audio visualizer + programs.cava.enable = true; + + programs.cava.settings = { + # Enable alacritty syncronized updates, removes flickering in alacritty + output.alacritty_sync = 1; + + general = { + mode = "normal"; + framerate = 60; + sensitivity = 100; + bars = 0; + bar_width = 1; + bar_spacing = 1; + }; + + smoothing = { + # Enable the fancy Monstercat smoothing + monstercat = 1; + # Wave mode + waves = 0; + # Gravity percentage for "drop off" + gravity = 100; + # Adjusts the integral and gravity filters to keep the signal smooth + noise_reduction = 77; + }; + + # Equalizer + eq = { + "1" = 1; + "2" = 1; + "3" = 1; + "4" = 1; + "5" = 1; + }; + }; +} diff --git a/programs/core/shell/default.nix b/system/shell/default.nix similarity index 100% rename from programs/core/shell/default.nix rename to system/shell/default.nix diff --git a/system/shell/pass.nix b/system/shell/pass.nix new file mode 100644 index 0000000..1cf3d4e --- /dev/null +++ b/system/shell/pass.nix @@ -0,0 +1,14 @@ +{ + config, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "password-store" { + programs.password-store = { + enable = true; + settings.PASSWORD_STORE_DIR = lib.mkDefault (throw "programs.password-store.settings.PASSWORD_STORE_DIR is not set"); + }; + + programs.password-store.package = pkgs.pass-wayland.withExtensions (p: with p; [pass-otp pass-audit pass-import pass-update pass-file pass-genphrase pass-checkup pass-tomb]); +} diff --git a/system/shell/shell-utils.nix b/system/shell/shell-utils.nix new file mode 100644 index 0000000..9a0f1de --- /dev/null +++ b/system/shell/shell-utils.nix @@ -0,0 +1,68 @@ +{ + config, + osConfig, + lib, + pkgs, + ... +}: +lib.utilMods.mkModule config "shell-utils" { + home.packages = with pkgs; + [ + # Fancy utilities + timer # Cooler timer in terminal + tldr # better man pages + entr # run commands when files change! + procs # Better ps + ventoy-full # bootable USB solution + dust # Better du and df + libnotify + ] + ++ lib.optionals (lib.conds.isWayland osConfig) [wl-clipboard wl-clipboard-x11] + ++ lib.optionals ((lib.conds.isX11 osConfig) && (!lib.conds.isWayland osConfig)) [ + xclip + xsel + xdotool + xorg.xwininfo + xorg.xprop + ]; + + # Custom colors for ls, grep and more + programs.dircolors.enable = true; + + # smart cd command, inspired by z and autojump + programs.zoxide.enable = true; + + # Shell extension to load and unload environment variables depending on the current directory. + programs.direnv = { + enable = true; + nix-direnv.enable = true; + #config = {}; + stdlib = ''export DIRENV_ACTIVE=1''; + }; + + # Much better ls replacement + programs.eza = { + enable = true; + git = true; + icons = "auto"; + extraOptions = ["--color=always" "--group-directories-first" "--classify"]; + }; + + # Fancy 'find' replacement + programs.fd = { + enable = true; + hidden = true; + ignores = [".git/" "*.bak"]; + }; + + # Fuzzy finder + programs.fzf = { + enable = true; + # Alt-C command options + changeDirWidgetOptions = ["--preview 'eza --tree --color=always {} | head -200'"]; + # Ctrl-T command options + fileWidgetOptions = ["--bind 'ctrl-/:change-preview-window(down|hidden|)'"]; + # Ctrl-R command options + historyWidgetOptions = ["--sort" "--exact"]; + }; +} diff --git a/system/shell/tmux.nix b/system/shell/tmux.nix new file mode 100644 index 0000000..5f00ee1 --- /dev/null +++ b/system/shell/tmux.nix @@ -0,0 +1,174 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.programs.tmux; +in + lib.utilMods.mkModule config "tmux" { + # Fixes issue where cava can't run under tmux + home.shellAliases = lib.mkIf config.modules.cava.enable {cava = "TERM=xterm-256color cava";}; + + programs.fzf.tmux.enableShellIntegration = true; + + programs.tmux = { + enable = true; + aggressiveResize = true; + customPaneNavigationAndResize = true; + baseIndex = 1; + historyLimit = 5000; + keyMode = "vi"; + mouse = true; + #escapeTime = 0; + shortcut = "a"; + terminal = "tmux-256color"; + resizeAmount = 15; + tmuxp.enable = true; + #newSession = true; + #secureSocket = false; + extraConfig = '' + # -- more settings --------------------------------------------------------------- + set -s set-clipboard on + set -g set-titles on + set -g set-titles-string "#S / #W / #(pwd)" + set -g allow-passthrough on + set -ga update-environment TERM + set -ga update-environment TERM_PROGRAM + + set-option -g status-right-length 100 + + # Enable sixel support + set -as terminal-features 'contour:sixel' + + # Enable full RGB support + set -as terminal-features ",*-256color:RGB" + + # Pane numbers, line messages duration and status line updates + set -g display-panes-time 800 + set -g display-time 2000 + set -g status-interval 5 + + # Monitor for terminal activity changes, and manage how the alerts are displayed + set -g monitor-activity on + set -g visual-activity both + + # update files on focus + set -g focus-events on + + setw -g automatic-rename on + # Renumber windows + set -g renumber-windows on + + # Change status bar position + set -g status-position bottom + # ------------------------------------------------------------------------------------- + + + # -- keybindings ----------------------------------------------------------------- + # reload config file (change file location to your the tmux.conf you want to use) + unbind R + bind -N "Reload configuration" r source-file ${config.xdg.configHome}/tmux/tmux.conf \; display "Reloaded!" + + unbind C-p + unbind C-n + + # Setup clipboard binding keys + unbind p + bind -N "Paste the most recent paste buffer" p paste-buffer + bind -N "Go back to previous window" P previous-window + + # Tmux-copycat functionality + # https://github.com/tmux-plugins/tmux-copycat/issues/148#issuecomment-997929971 + bind -N "Copy selection" -T copy-mode-vi y send -X copy-selection-no-clear + bind -N "Search backwards" / copy-mode \; send ? + # Somewhat tmux-copycat select url functionality (requires 3.1+) + bind -N "Select URL" C-u copy-mode \; send -X search-backward "(https?://|git@|git://|ssh://|ftp://|file:///)[[:alnum:]?=%/_.:,;~@!#$&()*+-]*" + + # Navigate panes using Alt-arrow without prefix + bind -N "Switch pane, left" -n M-Left select-pane -L + bind -N "Switch pane, right" -n M-Right select-pane -R + bind -N "Switch pane, up" -n M-Up select-pane -U + bind -N "Switch pane, down" -n M-Down select-pane -D + + # Join pane bindings + bind -N "Join panes horizitonally" = choose-window 'join-pane -h -s "%%"' + bind -N "Join panes vertically" + choose-window 'join-pane -s "%%"' + + # Split pane bindings + unbind '"' + unbind % + unbind n + unbind p + bind -N "Split panes horizontally" \\ split-window -h -c "#{pane_current_path}" + bind -N "Split panes horizontally, full window length" | split-window -fh -c "#{pane_current_path}" + bind -N "Split panes vertically" - split-window -v -c "#{pane_current_path}" + bind -N "Split panes vertically, full window length" _ split-window -fv -c "#{pane_current_path}" + + # Manage Session/Window + bind -N "Switch to next window" > next-window + bind -N "Switch to previous window" < previous-window + bind -N "Create new window" c new-window -c "#{pane_current_path}" + bind -N "Create new session" C-c new-session + bind -N "Toggle between windows" Space last-window + bind -N "Toggle between current and previous session" C-Space switch-client -l + bind -N "Jump to marked session" \` switch-client -t'{marked}' + unbind & + ${ + if cfg.disableConfirmationPrompt + then '' + bind -N "Kill the active pane" x kill-pane + bind -N "Kill the current window" X kill-window + bind -N "Kill the current session" C-x kill-session + '' + else '' + bind -N "Kill the current window" X confirm-before -p "kill-window #W? (y/n)" kill-window + bind -N "Kill the current session" C-x confirm-before -p "kill-session #W? (y/n)" kill-session + '' + } + + #Example + #bind -N "Example note" h split-window -h "vim ~/scratch/notes.md" + # ------------------------------------------------------------------------------------- + ''; + plugins = with pkgs.tmuxPlugins; [ + sensible + { + plugin = yank; + extraConfig = '' + # Enable Mouse support for tmux-yank + set -g @yank_with_mouse on + ''; + } + open + fuzzback + extrakto + (lib.mkIf config.programs.fzf.enable tmux-fzf) + { + plugin = dracula; + extraConfig = '' + # Theme settings + # available plugins: battery, cpu-usage, git, gpu-usage, ram-usage, tmux-ram-usage, network, network-bandwidth, network-ping, attached-clients, network-vpn, weather, time, spotify-tui, kubernetes-context, synchronize-panes + set -g @dracula-plugins "battery cpu-usage ram-usage time" + + # Show powerline symbols + set -g @dracula-show-powerline true + + # Enable window flags + set -g @dracula-show-flags true + + # Switch left icon, can accept `session`, `smiley`, `window`, or any character. + set -g @dracula-show-left-icon smiley + + # Hide empty plugins + set -g @dracula-show-empty-plugins false + + # Theme color settings + # available colors: white, gray, dark_gray, light_purple, dark_purple, cyan, green, orange, red, pink, yellow + # set -g @dracula-[plugin-name]-colors "[background] [foreground]" + set -g @dracula-gpu-usage-colors "red white" + ''; + } + ]; + }; + } diff --git a/system/shell/zsh.nix b/system/shell/zsh.nix new file mode 100644 index 0000000..75a3a48 --- /dev/null +++ b/system/shell/zsh.nix @@ -0,0 +1,140 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) utilMods mkIf; + hm-config = config.hm; +in + utilMods.mkModule config "zsh" { + # Forcibly Disable .zshenv + home-manager.sharedModules = [{home.file.".zshenv".enable = false;}]; + programs.zsh.enable = true; + # Source zshenv without ~/.zshenv + environment.etc."zshenv".text = ''export ZDOTDIR="$HOME"/.config/zsh''; + # Make zsh-completions work + environment.pathsToLink = ["/share/zsh"]; + + # Most of the configuration is done in Home-Manager + # Enable accompanying modules + hm.modules.atuin.enable = true; + hm.modules.oh-my-posh.enable = true; + + # The shell itself + hm.programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestion = { + enable = true; + #highlight = "underline"; + }; + syntaxHighlighting.enable = true; + dotDir = ".config/zsh"; + defaultKeymap = "viins"; + autocd = true; + history.path = "${hm-config.xdg.configHome}/zsh/.zsh_history"; + localVariables = { + # Make ZSH notifications expire, in miliseconds + AUTO_NOTIFY_EXPIRE_TIME = 5000; + # Make zsh-vi-mode be sourced + ZVM_INIT_MODE = "sourcing"; + # Disable zsh-vi-mode's custom cursors + ZVM_CURSOR_STYLE_ENABLED = false; + # Prompt message for auto correct + SPROMPT = "Correct $fg[red]%R$reset_color to $fg[green]%r$reset_color? [ny] "; + # Add more strategies to zsh-autosuggestions + ZSH_AUTOSUGGEST_STRATEGY = ["completion"]; + }; + initExtraFirst = '' + # If not running interactively, don't do anything + [[ $- != *i* ]] && return + ''; + + initExtra = '' + # Append extra variables + AUTO_NOTIFY_IGNORE+=("atuin" "yadm" "emacs" "nix-shell" "nix") + + setopt beep CORRECT # Enable terminal bell and autocorrect + autoload -U colors && colors # Enable colors + + ### Pyenv command + if command -v pyenv 1>/dev/null 2>&1; then + eval "$(pyenv init -)" + fi + + # set descriptions format to enable group support + zstyle ':completion:*:descriptions' format '[%d]' + + # set list-colors to enable filename colorizing + zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS} + + # disable sorting when completing any command + zstyle ':completion:complete:*:options' sort false + + # switch group using `,` and `.` + zstyle ':fzf-tab:*' switch-group ',' '.' + + # trigger continuous trigger with space key + zstyle ':fzf-tab:*' continuous-trigger 'space' + + # bind tab key to accept event + zstyle ':fzf-tab:*' fzf-bindings 'tab:accept' + + # accept and run suggestion with enter key + zstyle ':fzf-tab:*' accept-line enter + + ${ + if hm-config.programs.tmux.enable + then '' + # Enable fzf-tab integration with tmux + zstyle ':fzf-tab:*' fzf-command ftb-tmux-popup + zstyle ':fzf-tab:*' popup-min-size 100 50 + '' + else "" + } + ''; + + shellAliases = { + # ZSH globbing interferes with flake notation for all nix commands + nix = "noglob nix"; + nom = "noglob nom"; + nixos-remote = "noglob nixos-remote"; + nixos-rebuild = "noglob sudo nixos-rebuild"; + nh = "noglob nh"; + + # Append HISTFILE before running autin import to make it work properly + atuin-import = + mkIf hm-config.programs.atuin.enable + "export HISTFILE && atuin import auto && unset HISTFILE"; + }; + antidote = { + enable = true; + useFriendlyNames = true; + plugins = [ + #Docs https://github.com/jeffreytse/zsh-vi-mode#-usage + "jeffreytse/zsh-vi-mode" + + # Fish-like Plugins + "mattmc3/zfunctions" + "Aloxaf/fzf-tab" + "Freed-Wu/fzf-tab-source" + "MichaelAquilina/zsh-auto-notify" + + # Sudo escape + "ohmyzsh/ohmyzsh path:lib" + "ohmyzsh/ohmyzsh path:plugins/sudo" + + # Tmux integration + (mkIf hm-config.programs.tmux.enable + "ohmyzsh/ohmyzsh path:plugins/tmux") + + # Nix stuff + "chisui/zsh-nix-shell" + + # Make ZLE use system clipboard + "kutsan/zsh-system-clipboard" + ]; + }; + }; + } diff --git a/users/jeirmeister/config/git.nix b/users/jeirmeister/config/git.nix new file mode 100644 index 0000000..6d1f247 --- /dev/null +++ b/users/jeirmeister/config/git.nix @@ -0,0 +1,10 @@ +_: { + programs.git = { + userName = "NovaViper"; + userEmail = "coder.nova99@mailbox.org"; + signing = { + key = "DEAB6E5298F9C516"; + signByDefault = true; + }; + }; +} diff --git a/users/jeirmeister/config/kde6/common.nix b/users/jeirmeister/config/kde6/common.nix new file mode 100644 index 0000000..ae3093f --- /dev/null +++ b/users/jeirmeister/config/kde6/common.nix @@ -0,0 +1,63 @@ +{ + config, + pkgs, + ... +}: { + programs.plasma = { + enable = true; + kwin = { + titlebarButtons = { + left = ["close" "maximize" "minimize"]; + right = ["keep-above-windows" "on-all-desktops"]; + }; + borderlessMaximizedWindows = true; + }; + hotkeys.commands."restart-plasmashell" = { + name = "Restart Plasmashell"; + key = "Meta+Alt+R"; + command = "${pkgs.restart-plasma}/bin/restart-plasma"; + }; + configFile = { + ksmserverrc.General.loginMode = "restoreSavedSession"; # Force KDE to launch apps when a session was manually saved + kdeglobals = let + # Auto switch terminal application desktop file + terminal = + if builtins.hasAttr "TERMINAL" config.home.sessionVariables + then "${config.home.sessionVariables.TERMINAL}" + else "org.kde.konsole"; + in { + General.TerminalApplication = "${terminal}.destop"; + General.TerminalService = "${terminal}.desktop"; + }; + kservicemenurc.Show = { + "compressfileitemaction" = true; + "extractfileitemaction" = true; + "forgetfileitemaction" = true; + "installFont" = true; + "kactivitymanagerd_fileitem_linking_plugin" = true; + "kdeconnectfileitemaction" = true; + "kio-admin" = true; + "makefileactions" = true; + "mountisoaction" = true; + "plasmavaultfileitemaction" = true; + "runInKonsole" = true; + "slideshowfileitemaction" = true; + "tagsfileitemaction" = true; + "wallpaperfileitemaction" = true; + }; + dolphinrc = { + ContentDisplay.UsePermissionsFormat = "CombinedFormat"; + VersionControl.enabledPlugins = "Git"; + General = { + "AutoExpandFolders" = true; + "FilterBar" = true; + "ShowFullPathInTitlebar" = true; + "ShowToolTips" = true; + "SortingChoice" = "CaseInsensitiveSorting"; + "UseTabForSwitchingSplitView" = true; + }; + PreviewSettings.Plugins = "appimagethumbnail,audiothumbnail,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,ffmpegthumbs"; + }; + }; + }; +} diff --git a/users/jeirmeister/config/kde6/panels.nix b/users/jeirmeister/config/kde6/panels.nix new file mode 100644 index 0000000..a47bd90 --- /dev/null +++ b/users/jeirmeister/config/kde6/panels.nix @@ -0,0 +1,109 @@ +{ + config, + pkgs, + ... +}: { + home.packages = with pkgs; [plasma-panel-colorizer]; + + programs.plasma.panels = [ + # Windows like panel at the bottom + { + location = "bottom"; + height = 46; + floating = false; + widgets = [ + { + kickoff = { + icon = "nix-snowflake"; + sidebarPosition = "right"; + showButtonsFor = "powerAndSession"; + showActionButtonCaptions = false; + }; + } + "org.kde.plasma.marginsseparator" + { + iconTasks = { + appearance = { + showTooltips = true; + highlightWindows = true; + indicateAudioStreams = true; + fill = true; + }; + launchers = let + # Auto switch terminal application desktop file + terminal = + if builtins.hasAttr "TERMINAL" config.home.sessionVariables + then "${config.home.sessionVariables.TERMINAL}" + else "org.kde.konsole"; + in [ + "preferred://browser" + "applications:systemsettings.desktop" + "preferred://filemanager" + "applications:${terminal}.desktop" + "applications:emacsclient.desktop" + "applications:org.kde.krita.desktop" + "applications:writer.desktop" + ]; + }; + } + "org.kde.plasma.marginsseparator" + "org.kde.plasma.pager" + "org.kde.plasma.showdesktop" + ]; + } + { + location = "top"; + height = 26; + floating = true; + widgets = [ + { + applicationTitleBar = { + layout.elements = []; + windowControlButtons = { + iconSource = "breeze"; + buttonsAspectRatio = 95; + buttonsMargin = 0; + }; + windowTitle = { + source = "appName"; + hideEmptyTitle = true; + undefinedWindowTitle = ""; + margins = { + left = 5; + right = 5; + }; + }; + overrideForMaximized = { + enable = true; + elements = ["windowCloseButton" "windowMaximizeButton" "windowMinimizeButton" "windowIcon" "windowTitle"]; + source = "appName"; + }; + }; + } + "org.kde.plasma.appmenu" + "org.kde.plasma.panelspacer" + { + digitalClock = { + date = { + enable = true; + position = "besideTime"; + }; + time.showSeconds = "always"; + }; + } + "org.kde.plasma.panelspacer" + { + systemTray = { + icons.scaleToFit = true; + items = { + shown = [ + "org.kde.plasma.battery" + ]; + configs.battery.showPercentage = true; + }; + }; + } + ]; + } + ]; +} diff --git a/users/jeirmeister/config/pass.nix b/users/jeirmeister/config/pass.nix new file mode 100644 index 0000000..c3a2474 --- /dev/null +++ b/users/jeirmeister/config/pass.nix @@ -0,0 +1,3 @@ +{config, ...}: { + programs.password-store.settings.PASSWORD_STORE_DIR = "${config.home.homeDirectory}/Sync/.password-store"; +} diff --git a/users/jeirmeister/config/ssh.nix b/users/jeirmeister/config/ssh.nix new file mode 100644 index 0000000..6091f2e --- /dev/null +++ b/users/jeirmeister/config/ssh.nix @@ -0,0 +1,23 @@ +{config, ...}: { + programs.ssh.matchBlocks = { + "knoxpi-*" = { + hostname = "192.168.1.101"; + identityFile = "${config.home.homeDirectory}/.ssh/id_ecdsa_sk_rk_knox"; + port = 22; + extraOptions = { + RequestTTY = "yes"; + RemoteCommand = "tmux new-session -A -s \${%n}"; + }; + }; + "knoxpi" = { + hostname = "192.168.1.101"; + identityFile = "${config.home.homeDirectory}/.ssh/id_ecdsa_sk_rk_knox"; + port = 22; + }; + "printerpi" = { + user = "exova"; + hostname = "192.168.1.81"; + port = 22; + }; + }; +} diff --git a/users/jeirmeister/config/theme.nix b/users/jeirmeister/config/theme.nix new file mode 100644 index 0000000..1618720 --- /dev/null +++ b/users/jeirmeister/config/theme.nix @@ -0,0 +1,50 @@ +{ + config, + lib, + pkgs, + inputs, + ... +}: { + theme = { + packages = with pkgs; [dracula-theme]; + name = "Dracula"; + nameSymbolic = "dracula"; + app.rio.name = config.theme.name; + iconTheme = { + package = pkgs.papirus-icon-theme.override { + color = "violet"; + }; + name = "Papirus-Dark"; + }; + }; + + programs = { + plasma = let + workspace = { + lookAndFeel = "org.kde.breezedark.desktop"; + colorScheme = "DraculaPurple"; + #splashScreen = ""; + wallpaperSlideShow = { + path = ["${inputs.wallpapers}/"]; + interval = 300; + }; + }; + in { + overrideConfig = true; + inherit workspace; + kscreenlocker.appearance.wallpaperSlideShow = workspace.wallpaperSlideShow; + }; + cava.settings.color = { + gradient = 1; + gradient_count = 8; + gradient_color_1 = "'#8BE9FD'"; + gradient_color_2 = "'#9AEDFE'"; + gradient_color_3 = "'#CAA9FA'"; + gradient_color_4 = "'#BD93F9'"; + gradient_color_5 = "'#FF92D0'"; + gradient_color_6 = "'#FF79C6'"; + gradient_color_7 = "'#FF6E67'"; + gradient_color_8 = "'#FF5555'"; + }; + }; +} diff --git a/users/jeirmeister/config/virt-manager.nix b/users/jeirmeister/config/virt-manager.nix new file mode 100644 index 0000000..e45b5ea --- /dev/null +++ b/users/jeirmeister/config/virt-manager.nix @@ -0,0 +1,28 @@ +_: { + dconf.settings = { + "org/virt-manager/virt-manager" = { + system-tray = true; + xmleditor-enabled = true; + }; + + "org/virt-manager/virt-manager/connections" = { + autoconnect = ["qemu:///system"]; + uris = ["qemu:///system"]; + }; + + "org/virt-manager/virt-manager/stats" = { + enable-disk-poll = true; + enable-memory-poll = true; + enable-net-poll = true; + }; + + "org/virt-manager/virt-manager/console" = { + resize-guest = 1; + scaling = 2; + }; + + "org/virt-manager/virt-manager/new-vm" = { + cpu-default = "host-passthrough"; + }; + }; +} diff --git a/users/jeirmeister/config/vr.nix b/users/jeirmeister/config/vr.nix new file mode 100644 index 0000000..8fc2874 --- /dev/null +++ b/users/jeirmeister/config/vr.nix @@ -0,0 +1,21 @@ +{ + config, + osConfig, + lib, + ... +}: { + xdg.configFile = lib.mkIf osConfig.modules.gaming.vr.enable { + "alvr/session.json" = lib.dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "alvr/session.json"; + }; + /* + "openxr/1/active_runtime.json"= outputs.lib.mkDotsSymlink { + config = config; + user = config.home.username; + source = "alvr/active_runtime.json"; + }; + */ + }; +} diff --git a/users/jeirmeister/config/zsh.nix b/users/jeirmeister/config/zsh.nix new file mode 100644 index 0000000..cbdaaa4 --- /dev/null +++ b/users/jeirmeister/config/zsh.nix @@ -0,0 +1,60 @@ +{ + config, + osConfig, + lib, + pkgs, + ... +}: +with lib; { + xdg.configFile = mkMerge [ + (mkIf osConfig.modules.zsh.enable { + "zsh/.p10k.zsh" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "zsh/.p10k.zsh"; + }; + "zsh/functions" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "zsh/functions"; + }; + }) + + (mkIf config.modules.tmux.enable { + "tmuxp/session.yaml" = dots.mkDotsSymlink { + inherit config; + user = config.home.username; + source = "tmuxp/session.yaml"; + }; + }) + ]; + + home.packages = with pkgs; [ + # Terminal Decorations + toilet # Display fancy text in terminal + dwt1-shell-color-scripts # Display cool graphics in terminal + ]; + + programs.zsh = { + initExtraFirst = lib.mkAfter '' + ${ + if config.modules.tmux.enable + then '' + # Run Tmux on startup + if [ -z "$TMUX" ]; then + ${pkgs.tmux}/bin/tmux attach >/dev/null 2>&1 || ${pkgs.tmuxp}/bin/tmuxp load ${config.xdg.configHome}/tmuxp/session.yaml >/dev/null 2>&1 + exit + fi + '' + else "" + } + ''; + initExtra = lib.mkAfter '' + # Create shell prompt + if [ $(tput cols) -ge '75' ] || [ $(tput cols) -ge '100' ]; then + ${pkgs.toilet}/bin/toilet -f pagga "FOSS AND BEAUTIFUL" --metal + ${pkgs.fastfetch}/bin/fastfetch + fi + ''; + }; +} diff --git a/users/jeirmeister/dotfiles/alvr/active_runtime.json b/users/jeirmeister/dotfiles/alvr/active_runtime.json new file mode 100644 index 0000000..d813395 --- /dev/null +++ b/users/jeirmeister/dotfiles/alvr/active_runtime.json @@ -0,0 +1,8 @@ +{ + "file_format_version": "1.0.0", + "runtime": { + "VALVE_runtime_is_steamvr": true, + "library_path": "/home/novaviper/.local/share/Steam/steamapps/common/SteamVR/bin/linux64/vrclient.so", + "name": "SteamVR" + } +} diff --git a/users/jeirmeister/dotfiles/alvr/session.json b/users/jeirmeister/dotfiles/alvr/session.json new file mode 100644 index 0000000..c637275 --- /dev/null +++ b/users/jeirmeister/dotfiles/alvr/session.json @@ -0,0 +1,1139 @@ +{ + "server_version": "20.11.0", + "drivers_backup": null, + "openvr_config": { + "eye_resolution_width": 2592, + "eye_resolution_height": 2848, + "target_eye_resolution_width": 2592, + "target_eye_resolution_height": 2848, + "tracking_ref_only": false, + "enable_vive_tracker_proxy": false, + "aggressive_keyframe_resend": false, + "adapter_index": 0, + "codec": 0, + "h264_profile": 0, + "refresh_rate": 72, + "use_10bit_encoder": false, + "use_full_range_encoding": true, + "encoding_gamma": 1.0, + "enable_hdr": false, + "force_hdr_srgb_correction": false, + "clamp_hdr_extended_range": false, + "enable_pre_analysis": false, + "enable_vbaq": false, + "enable_hmqb": false, + "use_preproc": false, + "preproc_sigma": 4, + "preproc_tor": 7, + "amd_encoder_quality_preset": 0, + "rate_control_mode": 0, + "filler_data": false, + "entropy_coding": 1, + "force_sw_encoding": true, + "sw_thread_count": 11, + "controller_is_tracker": false, + "controllers_enabled": true, + "body_tracking_vive_enabled": false, + "body_tracking_has_legs": false, + "enable_foveated_encoding": true, + "foveation_center_size_x": 0.45, + "foveation_center_size_y": 0.4, + "foveation_center_shift_x": 0.4, + "foveation_center_shift_y": 0.1, + "foveation_edge_ratio_x": 4.0, + "foveation_edge_ratio_y": 5.0, + "enable_color_correction": true, + "brightness": 0.0, + "contrast": 0.0, + "saturation": 0.5, + "gamma": 1.0, + "sharpening": 0.5, + "linux_async_compute": false, + "linux_async_reprojection": false, + "nvenc_quality_preset": 5, + "nvenc_tuning_preset": 2, + "nvenc_multi_pass": 1, + "nvenc_adaptive_quantization_mode": 1, + "nvenc_low_delay_key_frame_scale": -1, + "nvenc_refresh_rate": -1, + "enable_intra_refresh": false, + "intra_refresh_period": -1, + "intra_refresh_count": -1, + "max_num_ref_frames": -1, + "gop_length": -1, + "p_frame_strategy": -1, + "nvenc_rate_control_mode": -1, + "rc_buffer_size": -1, + "rc_initial_delay": -1, + "rc_max_bitrate": -1, + "rc_average_bitrate": -1, + "nvenc_enable_weighted_prediction": false, + "capture_frame_dir": "", + "amd_bitrate_corruption_fix": false, + "use_separate_hand_trackers": true, + "_controller_profile": 1, + "_server_impl_debug": false, + "_client_impl_debug": false, + "_server_core_debug": false, + "_client_core_debug": false, + "_conncection_debug": false, + "_sockets_debug": false, + "_server_gfx_debug": false, + "_client_gfx_debug": false, + "_encoder_debug": false, + "_decoder_debug": false + }, + "client_connections": { + "3964.client": { + "display_name": "Quest 2", + "current_ip": "192.168.1.238", + "manual_ips": [], + "trusted": true, + "connection_state": "Disconnected", + "cabled": false + } + }, + "session_settings": { + "video": { + "bitrate": { + "gui_collapsed": false, + "mode": { + "ConstantMbps": 30, + "Adaptive": { + "gui_collapsed": true, + "saturation_multiplier": 0.95, + "max_bitrate_mbps": { + "enabled": false, + "content": 100 + }, + "min_bitrate_mbps": { + "enabled": false, + "content": 5 + }, + "max_network_latency_ms": { + "enabled": false, + "content": 8 + }, + "encoder_latency_limiter": { + "enabled": true, + "content": { + "max_saturation_multiplier": 0.9 + } + }, + "decoder_latency_limiter": { + "enabled": true, + "content": { + "gui_collapsed": false, + "max_decoder_latency_ms": 30, + "latency_overstep_frames": 90, + "latency_overstep_multiplier": 0.99 + } + } + }, + "variant": "ConstantMbps" + }, + "adapt_to_framerate": { + "enabled": false, + "content": { + "framerate_reset_threshold_multiplier": 2.0 + } + }, + "history_size": 256, + "image_corruption_fix": false + }, + "preferred_codec": { + "variant": "H264" + }, + "foveated_encoding": { + "enabled": true, + "content": { + "force_enable": false, + "center_size_x": 0.45, + "center_size_y": 0.4, + "center_shift_x": 0.4, + "center_shift_y": 0.1, + "edge_ratio_x": 4.0, + "edge_ratio_y": 5.0 + } + }, + "color_correction": { + "enabled": true, + "content": { + "brightness": 0.0, + "contrast": 0.0, + "saturation": 0.5, + "gamma": 1.0, + "sharpening": 0.5 + } + }, + "max_buffering_frames": 2.0, + "buffering_history_weight": 0.9, + "optimize_game_render_latency": true, + "encoder_config": { + "gui_collapsed": false, + "rate_control_mode": { + "variant": "Cbr" + }, + "filler_data": false, + "h264_profile": { + "variant": "High" + }, + "entropy_coding": { + "variant": "Cavlc" + }, + "use_10bit": false, + "use_full_range": true, + "encoding_gamma": 1.0, + "enable_hdr": false, + "force_hdr_srgb_correction": false, + "clamp_hdr_extended_range": false, + "nvenc": { + "gui_collapsed": true, + "quality_preset": { + "variant": "P5" + }, + "tuning_preset": { + "variant": "LowLatency" + }, + "multi_pass": { + "variant": "QuarterResolution" + }, + "adaptive_quantization_mode": { + "variant": "Spatial" + }, + "low_delay_key_frame_scale": -1, + "refresh_rate": -1, + "enable_intra_refresh": false, + "intra_refresh_period": -1, + "intra_refresh_count": -1, + "max_num_ref_frames": -1, + "gop_length": -1, + "p_frame_strategy": -1, + "rate_control_mode": -1, + "rc_buffer_size": -1, + "rc_initial_delay": -1, + "rc_max_bitrate": -1, + "rc_average_bitrate": -1, + "enable_weighted_prediction": false + }, + "amf": { + "gui_collapsed": true, + "quality_preset": { + "variant": "Quality" + }, + "enable_vbaq": false, + "enable_hmqb": false, + "use_preproc": false, + "preproc_sigma": 4, + "preproc_tor": 7, + "enable_pre_analysis": false + }, + "software": { + "force_software_encoding": true, + "thread_count": 11 + } + }, + "force_software_decoder": false, + "mediacodec_extra_options": { + "gui_collapsed": true, + "key": "", + "value": { + "Float": 0.0, + "Int32": 0, + "Int64": 0, + "String": "", + "variant": "Int32" + }, + "content": [ + [ + "operating-rate", + { + "Float": 0.0, + "Int32": 2147483647, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ], + [ + "priority", + { + "Float": 0.0, + "Int32": 0, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ], + [ + "vendor.qti-ext-dec-low-latency.enable", + { + "Float": 0.0, + "Int32": 1, + "Int64": 0, + "String": "", + "variant": "Int32" + } + ] + ] + }, + "transcoding_view_resolution": { + "Scale": 1.0, + "Absolute": { + "width": 2592, + "height": { + "set": false, + "content": 1072 + } + }, + "variant": "Absolute" + }, + "emulated_headset_view_resolution": { + "Scale": 1.0, + "Absolute": { + "width": 2592, + "height": { + "set": false, + "content": 1072 + } + }, + "variant": "Absolute" + }, + "preferred_fps": 72.0, + "adapter_index": 0, + "clientside_foveation": { + "enabled": false, + "content": { + "mode": { + "Static": { + "level": { + "variant": "High" + } + }, + "Dynamic": { + "max_level": { + "variant": "High" + } + }, + "variant": "Dynamic" + }, + "vertical_offset_deg": 0.0 + } + } + }, + "audio": { + "game_audio": { + "enabled": true, + "content": { + "gui_collapsed": false, + "device": { + "set": false, + "content": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + } + }, + "mute_when_streaming": true, + "buffering": { + "gui_collapsed": false, + "average_buffering_ms": 50, + "batch_ms": 10 + } + } + }, + "microphone": { + "enabled": true, + "content": { + "gui_collapsed": false, + "devices": { + "Custom": { + "sink": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + }, + "source": { + "NameSubstring": "", + "Index": 0, + "variant": "NameSubstring" + } + }, + "variant": "Automatic" + }, + "buffering": { + "gui_collapsed": false, + "average_buffering_ms": 50, + "batch_ms": 10 + } + } + } + }, + "headset": { + "position_recentering_mode": { + "Local": { + "view_height": 1.5 + }, + "variant": "LocalFloor" + }, + "rotation_recentering_mode": { + "variant": "Yaw" + }, + "controllers": { + "enabled": true, + "content": { + "gui_collapsed": false, + "tracked": true, + "hand_skeleton": { + "enabled": true, + "content": { + "steamvr_input_2_0": true + } + }, + "multimodal_tracking": false, + "hand_tracking_interaction": { + "enabled": false, + "content": { + "only_touch": false, + "pinch_touch_distance": 0.0, + "pinch_trigger_distance": 0.25, + "curl_touch_distance": 2.0, + "curl_trigger_distance": 2.5, + "joystick_deadzone": 40.0, + "joystick_offset_horizontal": 0.0, + "joystick_offset_vertical": 0.0, + "joystick_range": 1.0, + "activation_delay": 50, + "deactivation_delay": 100, + "repeat_delay": 100 + } + }, + "steamvr_pipeline_frames": 3.0, + "haptics": { + "enabled": true, + "content": { + "gui_collapsed": true, + "intensity_multiplier": 1.0, + "amplitude_curve": 1.0, + "min_duration_s": 0.01 + } + }, + "emulation_mode": { + "Custom": { + "serial_number": "ALVR Controller", + "button_set": { + "gui_collapsed": false, + "element": "/user/hand/left/input/a/click", + "content": [] + } + }, + "variant": "Quest2Touch" + }, + "extra_openvr_props": { + "gui_collapsed": true, + "element": { + "TrackingSystemName": "", + "ModelNumber": "", + "SerialNumber": "", + "RenderModelName": "", + "WillDriftInYaw": false, + "ManufacturerName": "", + "TrackingFirmwareVersion": "", + "HardwareRevisionString": "", + "AllWirelessDongleDescriptions": "", + "ConnectedWirelessDongle": "", + "DeviceIsWireless": false, + "DeviceIsCharging": false, + "DeviceBatteryPercentage": 0.0, + "FirmwareUpdateAvailable": false, + "FirmwareManualUpdate": false, + "FirmwareManualUpdateURL": "", + "HardwareRevisionUint64": 0, + "FirmwareVersion": 0, + "FPGAVersion": 0, + "VRCVersion": 0, + "RadioVersion": 0, + "DongleVersion": 0, + "BlockServerShutdown": false, + "CanUnifyCoordinateSystemWithHmd": false, + "ContainsProximitySensor": false, + "DeviceProvidesBatteryStatus": false, + "DeviceCanPowerOff": false, + "FirmwareProgrammingTarget": "", + "DeviceClass": 0, + "HasCamera": false, + "DriverVersion": "", + "FirmwareForceUpdateRequired": false, + "ViveSystemButtonFixRequired": false, + "ParentDriver": 0, + "ResourceRoot": "", + "RegisteredDeviceType": "", + "InputProfilePath": "", + "NeverTracked": false, + "NumCameras": 0, + "CameraFrameLayout": 0, + "CameraStreamFormat": 0, + "AdditionalDeviceSettingsPath": "", + "Identifiable": false, + "BootloaderVersion": 0, + "AdditionalSystemReportData": "", + "CompositeFirmwareVersion": "", + "FirmwareRemindUpdate": false, + "PeripheralApplicationVersion": 0, + "ManufacturerSerialNumber": "", + "ComputedSerialNumber": "", + "EstimatedDeviceFirstUseTime": 0, + "ReportsTimeSinceVSync": false, + "SecondsFromVsyncToPhotons": 0.0, + "DisplayFrequency": 0.0, + "UserIpdMeters": 0.0, + "CurrentUniverseId": 0, + "PreviousUniverseId": 0, + "DisplayFirmwareVersion": 0, + "IsOnDesktop": false, + "DisplayMCType": 0, + "DisplayMCOffset": 0.0, + "DisplayMCScale": 0.0, + "EdidVendorID": 0, + "DisplayMCImageLeft": "", + "DisplayMCImageRight": "", + "DisplayGCBlackClamp": 0.0, + "EdidProductID": 0, + "DisplayGCType": 0, + "DisplayGCOffset": 0.0, + "DisplayGCScale": 0.0, + "DisplayGCPrescale": 0.0, + "DisplayGCImage": "", + "LensCenterLeftU": 0.0, + "LensCenterLeftV": 0.0, + "LensCenterRightU": 0.0, + "LensCenterRightV": 0.0, + "UserHeadToEyeDepthMeters": 0.0, + "CameraFirmwareVersion": 0, + "CameraFirmwareDescription": "", + "DisplayFPGAVersion": 0, + "DisplayBootloaderVersion": 0, + "DisplayHardwareVersion": 0, + "AudioFirmwareVersion": 0, + "CameraCompatibilityMode": 0, + "ScreenshotHorizontalFieldOfViewDegrees": 0.0, + "ScreenshotVerticalFieldOfViewDegrees": 0.0, + "DisplaySuppressed": false, + "DisplayAllowNightMode": false, + "DisplayMCImageWidth": 0, + "DisplayMCImageHeight": 0, + "DisplayMCImageNumChannels": 0, + "SecondsFromPhotonsToVblank": 0.0, + "DriverDirectModeSendsVsyncEvents": false, + "DisplayDebugMode": false, + "GraphicsAdapterLuid": 0, + "DriverProvidedChaperonePath": "", + "ExpectedTrackingReferenceCount": 0, + "ExpectedControllerCount": 0, + "NamedIconPathControllerLeftDeviceOff": "", + "NamedIconPathControllerRightDeviceOff": "", + "NamedIconPathTrackingReferenceDeviceOff": "", + "DoNotApplyPrediction": false, + "DistortionMeshResolution": 0, + "DriverIsDrawingControllers": false, + "DriverRequestsApplicationPause": false, + "DriverRequestsReducedRendering": false, + "MinimumIpdStepMeters": 0.0, + "AudioBridgeFirmwareVersion": 0, + "ImageBridgeFirmwareVersion": 0, + "ImuFactoryGyroBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryGyroScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ConfigurationIncludesLighthouse20Features": false, + "AdditionalRadioFeatures": 0, + "ExpectedControllerType": "", + "HmdTrackingStyle": 0, + "DriverProvidedChaperoneVisibility": false, + "HmdColumnCorrectionSettingPrefix": "", + "CameraSupportsCompatibilityModes": false, + "SupportsRoomViewDepthProjection": false, + "DisplaySupportsMultipleFramerates": false, + "DisplayColorMultLeft": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplayColorMultRight": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplaySupportsRuntimeFramerateChange": false, + "DisplaySupportsAnalogGain": false, + "DisplayMinAnalogGain": 0.0, + "DisplayMaxAnalogGain": 0.0, + "DashboardScale": 0.0, + "IpdUIRangeMinMeters": 0.0, + "IpdUIRangeMaxMeters": 0.0, + "HmdSupportsHDCP14LegacyCompat": false, + "HmdSupportsMicMonitoring": false, + "DriverRequestedMuraCorrectionMode": 0, + "DriverRequestedMuraFeatherInnerLeft": 0, + "DriverRequestedMuraFeatherInnerRight": 0, + "DriverRequestedMuraFeatherInnerTop": 0, + "DriverRequestedMuraFeatherInnerBottom": 0, + "DriverRequestedMuraFeatherOuterLeft": 0, + "DriverRequestedMuraFeatherOuterRight": 0, + "DriverRequestedMuraFeatherOuterTop": 0, + "DriverRequestedMuraFeatherOuterBottom": 0, + "AudioDefaultPlaybackDeviceId": "", + "AudioDefaultRecordingDeviceId": "", + "AudioDefaultPlaybackDeviceVolume": 0.0, + "AudioSupportsDualSpeakerAndJackOutput": false, + "AttachedDeviceId": "", + "SupportedButtons": 0, + "Axis0Type": 0, + "Axis1Type": 0, + "Axis2Type": 0, + "Axis3Type": 0, + "Axis4Type": 0, + "ControllerRoleHint": 0, + "FieldOfViewLeftDegrees": 0.0, + "FieldOfViewRightDegrees": 0.0, + "FieldOfViewTopDegrees": 0.0, + "FieldOfViewBottomDegrees": 0.0, + "TrackingRangeMinimumMeters": 0.0, + "TrackingRangeMaximumMeters": 0.0, + "ModeLabel": "", + "CanWirelessIdentify": false, + "Nonce": 0, + "IconPathName": "", + "NamedIconPathDeviceOff": "", + "NamedIconPathDeviceSearching": "", + "NamedIconPathDeviceSearchingAlert": "", + "NamedIconPathDeviceReady": "", + "NamedIconPathDeviceReadyAlert": "", + "NamedIconPathDeviceNotReady": "", + "NamedIconPathDeviceStandby": "", + "NamedIconPathDeviceAlertLow": "", + "NamedIconPathDeviceStandbyAlert": "", + "OverrideContainer": 0, + "UserConfigPath": "", + "InstallPath": "", + "HasDisplayComponent": false, + "HasControllerComponent": false, + "HasCameraComponent": false, + "HasDriverDirectModeComponent": false, + "HasVirtualDisplayComponent": false, + "HasSpatialAnchorsSupport": false, + "ControllerType": "", + "ControllerHandSelectionPriority": 0, + "variant": "TrackingSystemName" + }, + "content": [] + }, + "linear_velocity_cutoff": 0.05, + "angular_velocity_cutoff": 10.0, + "left_controller_position_offset": { + "gui_collapsed": true, + "content": [ + 0.0, + 0.0, + -0.11 + ] + }, + "left_controller_rotation_offset": { + "gui_collapsed": true, + "content": [ + -20.0, + 0.0, + 0.0 + ] + }, + "left_hand_tracking_position_offset": { + "gui_collapsed": true, + "content": [ + 0.04, + -0.02, + -0.13 + ] + }, + "left_hand_tracking_rotation_offset": { + "gui_collapsed": true, + "content": [ + 0.0, + -45.0, + -90.0 + ] + }, + "button_mappings": { + "set": false, + "content": { + "gui_collapsed": false, + "key": "/user/hand/left/input/a/click", + "value": { + "gui_collapsed": false, + "element": { + "destination": "/user/hand/left/input/a/click", + "mapping_type": { + "HysteresisThreshold": { + "value": 0.5, + "deviation": 0.05 + }, + "BinaryToScalar": { + "off": 0.0, + "on": 1.0 + }, + "Remap": { + "min": 0.0, + "max": 1.0 + }, + "variant": "Passthrough" + }, + "binary_conditions": { + "gui_collapsed": true, + "element": "/user/hand/left/input/trigger/touch", + "content": [] + } + }, + "content": [] + }, + "content": [] + } + }, + "button_mapping_config": { + "gui_collapsed": true, + "click_threshold": { + "value": 0.5, + "deviation": 0.05 + }, + "touch_threshold": { + "value": 0.1, + "deviation": 0.05 + }, + "force_threshold": 0.8 + } + } + }, + "emulation_mode": { + "Custom": { + "serial_number": "Unknown" + }, + "variant": "Quest2" + }, + "extra_openvr_props": { + "gui_collapsed": true, + "element": { + "TrackingSystemName": "", + "ModelNumber": "", + "SerialNumber": "", + "RenderModelName": "", + "WillDriftInYaw": false, + "ManufacturerName": "", + "TrackingFirmwareVersion": "", + "HardwareRevisionString": "", + "AllWirelessDongleDescriptions": "", + "ConnectedWirelessDongle": "", + "DeviceIsWireless": false, + "DeviceIsCharging": false, + "DeviceBatteryPercentage": 0.0, + "FirmwareUpdateAvailable": false, + "FirmwareManualUpdate": false, + "FirmwareManualUpdateURL": "", + "HardwareRevisionUint64": 0, + "FirmwareVersion": 0, + "FPGAVersion": 0, + "VRCVersion": 0, + "RadioVersion": 0, + "DongleVersion": 0, + "BlockServerShutdown": false, + "CanUnifyCoordinateSystemWithHmd": false, + "ContainsProximitySensor": false, + "DeviceProvidesBatteryStatus": false, + "DeviceCanPowerOff": false, + "FirmwareProgrammingTarget": "", + "DeviceClass": 0, + "HasCamera": false, + "DriverVersion": "", + "FirmwareForceUpdateRequired": false, + "ViveSystemButtonFixRequired": false, + "ParentDriver": 0, + "ResourceRoot": "", + "RegisteredDeviceType": "", + "InputProfilePath": "", + "NeverTracked": false, + "NumCameras": 0, + "CameraFrameLayout": 0, + "CameraStreamFormat": 0, + "AdditionalDeviceSettingsPath": "", + "Identifiable": false, + "BootloaderVersion": 0, + "AdditionalSystemReportData": "", + "CompositeFirmwareVersion": "", + "FirmwareRemindUpdate": false, + "PeripheralApplicationVersion": 0, + "ManufacturerSerialNumber": "", + "ComputedSerialNumber": "", + "EstimatedDeviceFirstUseTime": 0, + "ReportsTimeSinceVSync": false, + "SecondsFromVsyncToPhotons": 0.0, + "DisplayFrequency": 0.0, + "UserIpdMeters": 0.0, + "CurrentUniverseId": 0, + "PreviousUniverseId": 0, + "DisplayFirmwareVersion": 0, + "IsOnDesktop": false, + "DisplayMCType": 0, + "DisplayMCOffset": 0.0, + "DisplayMCScale": 0.0, + "EdidVendorID": 0, + "DisplayMCImageLeft": "", + "DisplayMCImageRight": "", + "DisplayGCBlackClamp": 0.0, + "EdidProductID": 0, + "DisplayGCType": 0, + "DisplayGCOffset": 0.0, + "DisplayGCScale": 0.0, + "DisplayGCPrescale": 0.0, + "DisplayGCImage": "", + "LensCenterLeftU": 0.0, + "LensCenterLeftV": 0.0, + "LensCenterRightU": 0.0, + "LensCenterRightV": 0.0, + "UserHeadToEyeDepthMeters": 0.0, + "CameraFirmwareVersion": 0, + "CameraFirmwareDescription": "", + "DisplayFPGAVersion": 0, + "DisplayBootloaderVersion": 0, + "DisplayHardwareVersion": 0, + "AudioFirmwareVersion": 0, + "CameraCompatibilityMode": 0, + "ScreenshotHorizontalFieldOfViewDegrees": 0.0, + "ScreenshotVerticalFieldOfViewDegrees": 0.0, + "DisplaySuppressed": false, + "DisplayAllowNightMode": false, + "DisplayMCImageWidth": 0, + "DisplayMCImageHeight": 0, + "DisplayMCImageNumChannels": 0, + "SecondsFromPhotonsToVblank": 0.0, + "DriverDirectModeSendsVsyncEvents": false, + "DisplayDebugMode": false, + "GraphicsAdapterLuid": 0, + "DriverProvidedChaperonePath": "", + "ExpectedTrackingReferenceCount": 0, + "ExpectedControllerCount": 0, + "NamedIconPathControllerLeftDeviceOff": "", + "NamedIconPathControllerRightDeviceOff": "", + "NamedIconPathTrackingReferenceDeviceOff": "", + "DoNotApplyPrediction": false, + "DistortionMeshResolution": 0, + "DriverIsDrawingControllers": false, + "DriverRequestsApplicationPause": false, + "DriverRequestsReducedRendering": false, + "MinimumIpdStepMeters": 0.0, + "AudioBridgeFirmwareVersion": 0, + "ImageBridgeFirmwareVersion": 0, + "ImuFactoryGyroBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryGyroScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerBias": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ImuFactoryAccelerometerScale": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "ConfigurationIncludesLighthouse20Features": false, + "AdditionalRadioFeatures": 0, + "ExpectedControllerType": "", + "HmdTrackingStyle": 0, + "DriverProvidedChaperoneVisibility": false, + "HmdColumnCorrectionSettingPrefix": "", + "CameraSupportsCompatibilityModes": false, + "SupportsRoomViewDepthProjection": false, + "DisplaySupportsMultipleFramerates": false, + "DisplayColorMultLeft": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplayColorMultRight": { + "gui_collapsed": false, + "content": [ + 0.0, + 0.0, + 0.0 + ] + }, + "DisplaySupportsRuntimeFramerateChange": false, + "DisplaySupportsAnalogGain": false, + "DisplayMinAnalogGain": 0.0, + "DisplayMaxAnalogGain": 0.0, + "DashboardScale": 0.0, + "IpdUIRangeMinMeters": 0.0, + "IpdUIRangeMaxMeters": 0.0, + "HmdSupportsHDCP14LegacyCompat": false, + "HmdSupportsMicMonitoring": false, + "DriverRequestedMuraCorrectionMode": 0, + "DriverRequestedMuraFeatherInnerLeft": 0, + "DriverRequestedMuraFeatherInnerRight": 0, + "DriverRequestedMuraFeatherInnerTop": 0, + "DriverRequestedMuraFeatherInnerBottom": 0, + "DriverRequestedMuraFeatherOuterLeft": 0, + "DriverRequestedMuraFeatherOuterRight": 0, + "DriverRequestedMuraFeatherOuterTop": 0, + "DriverRequestedMuraFeatherOuterBottom": 0, + "AudioDefaultPlaybackDeviceId": "", + "AudioDefaultRecordingDeviceId": "", + "AudioDefaultPlaybackDeviceVolume": 0.0, + "AudioSupportsDualSpeakerAndJackOutput": false, + "AttachedDeviceId": "", + "SupportedButtons": 0, + "Axis0Type": 0, + "Axis1Type": 0, + "Axis2Type": 0, + "Axis3Type": 0, + "Axis4Type": 0, + "ControllerRoleHint": 0, + "FieldOfViewLeftDegrees": 0.0, + "FieldOfViewRightDegrees": 0.0, + "FieldOfViewTopDegrees": 0.0, + "FieldOfViewBottomDegrees": 0.0, + "TrackingRangeMinimumMeters": 0.0, + "TrackingRangeMaximumMeters": 0.0, + "ModeLabel": "", + "CanWirelessIdentify": false, + "Nonce": 0, + "IconPathName": "", + "NamedIconPathDeviceOff": "", + "NamedIconPathDeviceSearching": "", + "NamedIconPathDeviceSearchingAlert": "", + "NamedIconPathDeviceReady": "", + "NamedIconPathDeviceReadyAlert": "", + "NamedIconPathDeviceNotReady": "", + "NamedIconPathDeviceStandby": "", + "NamedIconPathDeviceAlertLow": "", + "NamedIconPathDeviceStandbyAlert": "", + "OverrideContainer": 0, + "UserConfigPath": "", + "InstallPath": "", + "HasDisplayComponent": false, + "HasControllerComponent": false, + "HasCameraComponent": false, + "HasDriverDirectModeComponent": false, + "HasVirtualDisplayComponent": false, + "HasSpatialAnchorsSupport": false, + "ControllerType": "", + "ControllerHandSelectionPriority": 0, + "variant": "TrackingSystemName" + }, + "content": [] + }, + "tracking_ref_only": false, + "enable_vive_tracker_proxy": false, + "face_tracking": { + "enabled": false, + "content": { + "gui_collapsed": true, + "sources": { + "combined_eye_gaze": true, + "eye_tracking_fb": true, + "face_tracking_fb": true, + "eye_expressions_htc": true, + "lip_expressions_htc": true + }, + "sink": { + "VrchatEyeOsc": { + "port": 9000 + }, + "variant": "VrchatEyeOsc" + } + } + }, + "body_tracking": { + "enabled": false, + "content": { + "gui_collapsed": true, + "sources": { + "body_tracking_fb": { + "enabled": true, + "content": { + "full_body": true + } + } + }, + "sink": { + "VrchatBodyOsc": { + "port": 9000 + }, + "variant": "FakeViveTracker" + }, + "tracked": true + } + } + }, + "connection": { + "stream_protocol": { + "variant": "Udp" + }, + "client_discovery": { + "enabled": true, + "content": { + "auto_trust_clients": false + } + }, + "on_connect_script": "", + "on_disconnect_script": "", + "avoid_video_glitching": false, + "packet_size": 1400, + "stream_port": 9944, + "web_server_port": 8082, + "osc_local_port": 9942, + "server_send_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "server_recv_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "client_send_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "client_recv_buffer_bytes": { + "Custom": 100000, + "variant": "Maximum" + }, + "max_queued_server_video_frames": 1024, + "statistics_history_size": 256, + "aggressive_keyframe_resend": false, + "dscp": { + "set": false, + "content": { + "ClassSelector": 7, + "AssuredForwarding": { + "class": 4, + "drop_probability": { + "variant": "Low" + } + }, + "variant": "ExpeditedForwarding" + } + } + }, + "extra": { + "steamvr_launcher": { + "driver_launch_action": { + "variant": "UnregisterOtherDriversAtStartup" + }, + "open_close_steamvr_with_dashboard": true + }, + "capture": { + "startup_video_recording": false, + "rolling_video_files": { + "enabled": false, + "content": { + "duration_s": 5 + } + }, + "capture_frame_dir": "" + }, + "logging": { + "show_notification_tip": true, + "prefer_backtrace": false, + "notification_level": { + "variant": "Warning" + }, + "client_log_report_level": { + "enabled": true, + "content": { + "variant": "Error" + } + }, + "show_raw_events": { + "enabled": false, + "content": { + "hide_spammy_events": false + } + }, + "log_to_disk": false, + "log_tracking": false, + "log_button_presses": false, + "log_haptics": false, + "debug_groups": { + "server_impl": false, + "client_impl": false, + "server_core": false, + "client_core": false, + "connection": false, + "sockets": false, + "server_gfx": false, + "client_gfx": false, + "encoder": false, + "decoder": false + } + }, + "patches": { + "linux_async_compute": false, + "linux_async_reprojection": false + }, + "open_setup_wizard": false + } + } +} \ No newline at end of file diff --git a/users/jeirmeister/dotfiles/kitty/default.conf b/users/jeirmeister/dotfiles/kitty/default.conf new file mode 100644 index 0000000..c73db8b --- /dev/null +++ b/users/jeirmeister/dotfiles/kitty/default.conf @@ -0,0 +1,10 @@ +# Set the working directory for windows in the current tab +#cd ~ + +#Launch shell +launch . + +#Launch shell +launch . + +launch cava diff --git a/users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json b/users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json new file mode 100644 index 0000000..0cdaeca --- /dev/null +++ b/users/jeirmeister/dotfiles/openrgb/rgb-default-effect.json @@ -0,0 +1,95 @@ +{ + "Effects": [ + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 100, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 0 + } + ], + "CustomName": "", + "EffectClassName": "Breathing", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 1, + "Speed": 160, + "Temperature": 0, + "Tint": 0, + "UserColors": [16715419] + }, + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 100, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 3 + } + ], + "CustomName": "", + "EffectClassName": "Visor", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 20, + "Speed": 50, + "Temperature": 0, + "Tint": 0, + "UserColors": [8323327, 8323327] + }, + { + "AllowOnlyFirst": false, + "AutoStart": true, + "Brightness": 50, + "ControllerZones": [ + { + "description": "MSI Mystic Light Device (185-byte)", + "is_segment": false, + "location": "HID: /dev/hidraw3", + "name": "MSI MPG B550 GAMING PLUS (MS-7C56)", + "reverse": false, + "segment_idx": -1, + "self_brightness": 100, + "serial": "A02021090806", + "vendor": "MSI", + "version": "AP/LD 0.6 / 1.5", + "zone_idx": 1 + } + ], + "CustomName": "", + "CustomSettings": { + "background": 0 + }, + "EffectClassName": "MotionPoint", + "FPS": 60, + "RandomColors": false, + "Slider2Val": 1, + "Speed": 25, + "Temperature": 0, + "Tint": 0, + "UserColors": [16715354] + } + ], + "version": 2 +} diff --git a/users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json b/users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json new file mode 100644 index 0000000..f7e2dd8 --- /dev/null +++ b/users/jeirmeister/dotfiles/openrgb/rgb-effect-settings.json @@ -0,0 +1,27 @@ +{ + "audio_settings": { + "amplitude": 100, + "audio_device": -1, + "avg_mode": 0, + "avg_size": 8, + "decay": 80, + "equalizer": [ + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0 + ], + "filter_constant": 1.0, + "nrml_ofst": 0.03999999910593033, + "nrml_scl": 0.5, + "window_mode": 0 + }, + "brightness": 100, + "fps": 60, + "fpscapture": 60, + "hide_unsupported": false, + "prefer_random": false, + "prefered_colors": [], + "startup_profile": "default", + "temperature": 0, + "tint": 0, + "use_prefered_colors": false +} diff --git a/users/jeirmeister/dotfiles/tmuxp/session.yaml b/users/jeirmeister/dotfiles/tmuxp/session.yaml new file mode 100644 index 0000000..0dd01b5 --- /dev/null +++ b/users/jeirmeister/dotfiles/tmuxp/session.yaml @@ -0,0 +1,13 @@ +session_name: 3-panes +windows: + - default: + layout: 63bb,132x42,0,0{83x42,0,0,0,48x42,84,0[48x21,84,0,1,48x20,84,22,2]} + panes: + - shell_command: + - + focus: true + - + - environment: + TERM: "xterm-256color" + shell_command: cava + #- cmatrix -ba -u 3 -C blue diff --git a/users/jeirmeister/monsterbabe.nix b/users/jeirmeister/monsterbabe.nix new file mode 100644 index 0000000..2c8c1cf --- /dev/null +++ b/users/jeirmeister/monsterbabe.nix @@ -0,0 +1,24 @@ +{ + config, + lib, + pkgs, + username, + osConfig, + ... +}: { + xdg.configFile = { + "OpenRGB/plugins/settings/effect-profiles/default".source = lib.dots.getDotsPath { + user = username; + path = "openrgb/rgb-default-effect.json"; + }; + "OpenRGB/plugins/settings/EffectSettings.json".source = lib.dots.getDotsPath { + user = username; + path = "openrgb/rgb-effect-settings.json"; + }; + }; + + programs.rio.settings.window = { + width = 1000; + height = 600; + }; +} diff --git a/users/jeirmeister/steamdeck.nix b/users/jeirmeister/steamdeck.nix new file mode 100644 index 0000000..c67582f --- /dev/null +++ b/users/jeirmeister/steamdeck.nix @@ -0,0 +1,13 @@ +{ + config, + lib, + pkgs, + ... +}: { + home.packages = with pkgs; [moonlight-qt]; + + programs.rio.settings.window = { + width = 1200; + height = 800; + }; +} diff --git a/users/jeirmeister/system.nix b/users/jeirmeister/system.nix new file mode 100644 index 0000000..f11f7c9 --- /dev/null +++ b/users/jeirmeister/system.nix @@ -0,0 +1,168 @@ +{ + config, + lib, + pkgs, + username, + inputs, + ... +}: let + agenixHashedPasswordFile = lib.optionalString (lib.hasAttr "agenix" inputs) config.age.secrets."${username}-password".path; +in { + variables.user = { + fullName = "Nova Leary"; + emailAddress = "coder.nova99@mailbox.org"; + }; + variables.userIdentityPaths = lib.secrets.mkSecretIdentities ["age-yubikey-identity-a38cb00a-usba.txt"]; + + users.users.${username} = { + shell = pkgs.zsh; + extraGroups = [ + "networkmanager" + "wheel" + "video" + "audio" + "libvirtd" + "scanner" + "i2c" + "git" + "gamemode" + ]; + hashedPasswordFile = agenixHashedPasswordFile; + }; + + time.timeZone = lib.mkForce "America/Chicago"; + + # User Secrets + age.secrets."${username}-password" = lib.secrets.mkSecretFile { + user = username; + source = "passwd.age"; + }; + + # Make CAPS LOCK become CTRL key for Emacs + services.xserver.xkb.options = "terminate:ctrl_alt_bksp,caps:ctrl_modifier"; + + programs.localsend.enable = true; + + # Modules for system live under ../../modules/system + modules = lib.utils.enable [ + # Terminal + "zsh" + + # Hardware + "yubikey" + + # Services + "syncthing" + ]; + + stylix = { + enable = true; + polarity = "dark"; + base16Scheme = lib.mkForce "${pkgs.base16-schemes}/share/themes/dracula.yaml"; + image = "${inputs.wallpapers}/purple-mountains-ai.png"; + override = { + scheme = "BetterDracula"; + base00 = "282a36"; + base01 = "363447"; + base02 = "44475a"; + base03 = "6272a4"; + base04 = "9ea8c7"; + base05 = "f8f8f2"; + base06 = "f0f1f4"; + base07 = "ffffff"; + base08 = "ff5555"; + base09 = "ffb86c"; + base0A = "f1fa8c"; + base0B = "50fa7b"; + base0C = "8be9fd"; + base0D = "80bfff"; + base0E = "ff79c6"; + base0F = "bd93f9"; + }; + cursor = { + package = pkgs.capitaine-cursors; + name = "capitaine-cursors-white"; + size = 24; + }; + fonts = let + sansSerif = { + package = pkgs.nerdfonts; + name = "NotoSans Nerd Font"; + }; + serif = sansSerif; + monospace = { + package = pkgs.nerdfonts; + name = "0xProto Nerd Font Mono"; + }; + emoji = { + package = pkgs.noto-fonts-emoji; + name = "Noto Color Emoji"; + }; + sizes = { + applications = 10; + desktop = 10; + popups = 10; + terminal = 11; + }; + in {inherit sansSerif serif monospace emoji sizes;}; + opacity = { + applications = 1.0; + desktop = 1.0; + popups = 1.0; + terminal = 1.0; + }; + }; + + # Modules for users live under ../../modules/home + hm.variables = { + defaultTerminal = "kitty"; + defaultBrowser = "floorp"; + defaultTextEditor = "doom-emacs"; + }; + + hm.home.packages = with pkgs; [openscad freecad rpi-imager blisp libreoffice-qt6-fresh keepassxc krita kdePackages.tokodon]; + + hm.stylix.targets = lib.mkForce { + # Enable 256 colors for kitty + kitty.variant256Colors = true; + # Causes some mismatched colors with Dracula-tmux theme + tmux.enable = false; + # Disable stylix's KDE module, very broken currently + kde.enable = false; + }; + + hm.age.secrets."borg_token" = lib.secrets.mkSecretFile { + user = username; + source = "borg.age"; + destination = "${config.hm.xdg.configHome}/borg/keys/srv_dev_disk_by_uuid_5aaed6a3_d2c7_4623_b121_5ebb8d37d930_Backups"; + }; + hm.modules = lib.utils.enable [ + # Core + "git" + "doom-emacs" + "password-store" + + # Terminal Utils + "shell-utils" + "nix" + "cava" + "tmux" + "bat" + "btop" + "fastfetch" + "topgrade" + + # Development Environment + "latex" + "lua" + "markdown" + "python" + "rust" + + # Applications + #"vivaldi" + "jellyfin-player" + "borg" + "discord" + ]; +}