├── .github └── FUNDING.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ └── codeStyleConfig.xml ├── dotfiles.iml ├── misc.xml ├── modules.xml ├── runConfigurations │ ├── build_users_jacob.xml │ └── eval_hyprland_conf.xml └── vcs.xml ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── flake.lock ├── flake.nix ├── hardware └── amd-thinkpad │ ├── airplane-mode.nix │ ├── bootloader.nix │ ├── common.nix │ ├── disable-input-devices.nix │ └── graphics.nix ├── hm-modules ├── armcord.nix ├── disable-input │ ├── common.nix │ ├── default.nix │ └── disable-devices-notify.sh ├── halloy.nix ├── idlehack.nix ├── keepassxc.nix ├── kvantum.nix ├── osd-functions │ ├── default.nix │ ├── functions.sh │ ├── icons │ │ ├── LICENSE │ │ ├── README │ │ └── rounded-white │ │ │ ├── mic_off_white_36dp.svg │ │ │ ├── mic_white_36dp.svg │ │ │ ├── volume_down_white_36dp.svg │ │ │ ├── volume_off_white_36dp.svg │ │ │ └── volume_up_white_36dp.svg │ └── package.nix ├── randbg │ ├── default.nix │ └── wallpaper.sh ├── steam.nix ├── swayidle.nix ├── vesktop.nix ├── webcord.nix └── zsh │ ├── default.nix │ └── integrations.nix ├── hosts ├── intrepid │ ├── default.nix │ ├── filesystems.nix │ ├── misc.nix │ └── powerplan.nix ├── odyssey │ ├── cpu-frequency.nix │ ├── default.nix │ ├── filesystems.nix │ ├── misc.nix │ ├── packages.nix │ └── powerplan.nix └── shared │ ├── amd-thinkpad │ └── plymouth.nix │ ├── gamemode.nix │ ├── nix-registry.nix │ ├── nixbuild.nix │ ├── packages.nix │ ├── peripherals.nix │ ├── pia-openvpn.nix │ ├── run-game.nix │ ├── touchpad-fix.nix │ └── user-sessions.nix ├── lib ├── colors │ ├── default.nix │ └── palettes │ │ └── gruvbox.nix └── default.nix ├── misc ├── eww │ ├── default.nix │ ├── eww.scss │ ├── eww.yuck │ └── icons │ │ └── battery │ │ ├── battery-10.svg │ │ ├── battery-20.svg │ │ ├── battery-30.svg │ │ ├── battery-40.svg │ │ ├── battery-50.svg │ │ ├── battery-60.svg │ │ ├── battery-70.svg │ │ ├── battery-80.svg │ │ └── battery-90.svg ├── refind-nvme.sh └── zorin │ ├── grub-hdd-to-nvme.sh │ └── logind-hibernate.sh ├── modules ├── amdctl │ ├── apply-pstate-voltages.sh │ └── default.nix ├── disable-input-devices.nix ├── qmk-devices.nix └── uwsm.nix ├── overlays ├── default.nix ├── hacks │ └── nixpkgs-config-exceptions.nix ├── lib.nix ├── oraclejdk.nix ├── patches.nix └── updates.nix ├── packages ├── amdctl.nix ├── default.nix ├── firefox-extensions.nix ├── fork-awesome.nix ├── idlehack.nix ├── ja-netfilter │ ├── base.nix │ ├── default.nix │ └── packages.nix ├── java │ ├── default.nix │ ├── graalvm-ce-sources.json │ └── temurin-sources.json ├── json2nix.nix ├── lib │ ├── default.nix │ └── wrapper-tools.nix ├── nerdfonts.nix ├── overlays.nix ├── platformio-python.nix ├── proton-ge-custom.nix ├── prtsc │ ├── default.nix │ └── prtsc.pl ├── ttf-ms-win11 │ ├── default.nix │ └── hashes.nix ├── wavefox.nix └── zsh-plugins.nix ├── scripts ├── airplane-mode.sh ├── cleanup.sh ├── dots.nix ├── dots.sh ├── json2nix.sh ├── mount.sh ├── partition.sh └── run-game.sh ├── secrets ├── jacob.spotifyd.age ├── root.nix-access-tokens-github.age ├── root.pia-user-pass.age └── secrets.nix └── users ├── jacob ├── hyprland │ ├── config.nix │ ├── default.nix │ ├── kanshi.nix │ ├── keybinds.nix │ ├── keymaps.nix │ ├── scripts │ │ ├── default.nix │ │ ├── hypr-alt-tab │ │ │ ├── .gitignore │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── default.nix │ │ │ └── src │ │ │ │ └── main.rs │ │ ├── pin-window.sh │ │ ├── screenshot.sh │ │ ├── silent-running.sh │ │ ├── switch-keyboard-layout.nu │ │ └── toggle-group-or-lock.sh │ ├── waybar.nix │ ├── waybar.scss │ └── windowrules.nix ├── mimeApps.nix ├── profile.nix ├── programs │ ├── alacritty.nix │ ├── armcord.nix │ ├── default.nix │ ├── discord │ │ ├── default.nix │ │ └── webcord-config.json │ ├── firefox │ │ ├── blocking.nix │ │ └── default.nix │ ├── fish.nix │ ├── jetbrains.nix │ ├── spotify.nix │ ├── starship.nix │ ├── vesktop.nix │ ├── vscode │ │ ├── enable.nix │ │ ├── keybinds │ │ │ └── spikespaz.nix │ │ ├── languages │ │ │ ├── bash.nix │ │ │ ├── cpp.nix │ │ │ ├── hare.nix │ │ │ ├── nix.nix │ │ │ ├── nushell.nix │ │ │ ├── perl.nix │ │ │ ├── python.nix │ │ │ ├── rust.nix │ │ │ ├── web.nix │ │ │ └── yuck.nix │ │ ├── marketplace.nix │ │ ├── other │ │ │ ├── marlin.nix │ │ │ └── marp.nix │ │ └── settings │ │ │ └── spikespaz.nix │ ├── zed │ │ └── default.nix │ └── zsh.nix ├── services │ ├── default.nix │ ├── easyeffects.nix │ ├── onedrive.nix │ └── spotify.nix └── wayland │ ├── default.nix │ ├── dunst.nix │ ├── gammastep.nix │ ├── gruvbox-rofi.rasi │ ├── gui-theme.nix │ ├── kde-theme.nix │ ├── rofi.nix │ ├── spotlight-dark.rasi │ ├── suite.nix │ ├── swaylock.nix │ ├── text-search.svg │ ├── timeouts.nix │ ├── utilities.nix │ └── wlogout.nix ├── jacob@intrepid ├── default.nix └── hyprland │ ├── config.nix │ ├── default.nix │ └── monitors.nix └── jacob@odyssey ├── default.nix ├── hyprland ├── config.nix ├── default.nix └── monitors.nix └── profile-override.nix /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: spikespaz 2 | ko_fi: spikespaz 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | scratch.nix 2 | inputs 3 | result 4 | result-man 5 | .Trash-1000 6 | .pls_cache 7 | flake.lock.* 8 | .directory 9 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dotfiles.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/build_users_jacob.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/eval_hyprland_conf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.enableFiletypes": [ 3 | "nix" 4 | ], 5 | "nixEnvSelector.nixFile": "${workspaceRoot}/flake.nix", 6 | "cSpell.words": [ 7 | "alacritty", 8 | "anydesk", 9 | "attrsets", 10 | "birdos", 11 | "bootloader", 12 | "cachix", 13 | "clion", 14 | "coreutils", 15 | "cura", 16 | "filesystems", 17 | "filezilla", 18 | "findutils", 19 | "fontconfig", 20 | "fullscreen", 21 | "gamescope", 22 | "goland", 23 | "graalvm", 24 | "hexchat", 25 | "homeage", 26 | "hyprland", 27 | "intellij", 28 | "jdks", 29 | "jellyfin", 30 | "jetbrains", 31 | "keepassxc", 32 | "lapce", 33 | "libsecret", 34 | "libva", 35 | "mailspring", 36 | "marp", 37 | "neofetch", 38 | "neovim", 39 | "nixbuild", 40 | "ntfs", 41 | "nushell", 42 | "onedrive", 43 | "onlyoffice", 44 | "openscad", 45 | "powerplan", 46 | "prealloc", 47 | "prismlauncher", 48 | "procps", 49 | "prusa", 50 | "qbittorrent", 51 | "ragenix", 52 | "relatime", 53 | "remmina", 54 | "rgba", 55 | "rustdesk", 56 | "rustup", 57 | "showmeta", 58 | "substituters", 59 | "swaybg", 60 | "temurin", 61 | "thinkpad", 62 | "touchpad", 63 | "virt", 64 | "webcord" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /hardware/amd-thinkpad/airplane-mode.nix: -------------------------------------------------------------------------------- 1 | { self, lib, pkgs, ... }: 2 | let 3 | # The hardware already gets soft-blocked, but I want a button to restart the driver if it acts up. 4 | # I will bind this to SHIFT + XF86WLAN. 5 | airplane-mode = 6 | (pkgs.patchShellScript "${self}/scripts/airplane-mode.sh" rec { 7 | name = "airplane-mode"; 8 | destination = "/bin/${name}"; 9 | # runtimeInputs = [ ]; 10 | # overrideEnvironment = { }; 11 | }); 12 | in { 13 | environment.systemPackages = [ airplane-mode ]; 14 | 15 | security.sudo.extraRules = [{ 16 | groups = [ "users" ]; 17 | commands = [{ 18 | command = lib.getExe airplane-mode; 19 | options = [ "NOPASSWD" ]; 20 | }]; 21 | }]; 22 | } 23 | -------------------------------------------------------------------------------- /hardware/amd-thinkpad/bootloader.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, ... }: 2 | ########################## 3 | ### BOOT CONFIGURATION ### 4 | ########################## 5 | { 6 | # systemd pivots to ramfs on shutdown 7 | # this is so that the root fs can be unmounted safely 8 | # it is not worth my time, I live on the edge 9 | systemd.shutdownRamfs.enable = false; 10 | 11 | boot = { 12 | kernelModules = [ "acpi_call" ]; 13 | extraModulePackages = with config.boot.kernelPackages; [ acpi_call ]; 14 | 15 | initrd.availableKernelModules = [ "usb_storage" "rtsx_pci_sdmmc" ]; 16 | initrd.kernelModules = [ "amdgpu" "nvme" ]; 17 | 18 | initrd.systemd.strip = false; 19 | initrd.systemd.enable = true; 20 | 21 | loader = { 22 | # could be a little faster 23 | # TODO can this be done for plymouth? 24 | generationsDir.copyKernels = true; 25 | 26 | systemd-boot.enable = true; 27 | systemd-boot.editor = false; 28 | systemd-boot.configurationLimit = 10; 29 | 30 | # need to hold space to get the boot menu to appear 31 | timeout = 0; 32 | 33 | efi.efiSysMountPoint = "/boot"; 34 | # TODO maybe? 35 | # efi.canTouchEfiVariables = true; 36 | }; 37 | 38 | kernelParams = [ 39 | # Checked `dmesg`, it suggested that I add this. 40 | # Not sure if this is placebo, but I seem to notice 41 | # pointer acceleration being slightly smoother. 42 | # Anyway, it doesn't seem to hurt. 43 | "psmouse.synaptics_intertouch=1" 44 | ]; 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /hardware/amd-thinkpad/common.nix: -------------------------------------------------------------------------------- 1 | { 2 | hardware = { 3 | # update processor firmware by loading from memory at boot 4 | cpu.amd.updateMicrocode = true; 5 | 6 | # enable proprietary firmware that is still redistributable 7 | # required for some hardware, drivers contain proprietary blobs 8 | enableRedistributableFirmware = true; 9 | 10 | # wifi adapter 11 | # error: rtw89-firmware has been removed because linux-firmware now contains it. 12 | # firmware = [pkgs.rtw89-firmware]; 13 | 14 | # enable bluetooth but turn off power by default 15 | bluetooth.enable = true; 16 | bluetooth.powerOnBoot = false; 17 | }; 18 | 19 | # firmware updater for machine hardware 20 | services.fwupd.enable = true; 21 | 22 | # enable fingerprint sensor 23 | services.fprintd.enable = true; 24 | 25 | # networking.networkmanager.enable = true; 26 | # networking.networkmanager.wifi.backend = "iwd"; 27 | networking.wireless.iwd.enable = true; 28 | # bluetooth 29 | services.blueman.enable = true; 30 | 31 | # audio and video drivers with legacy alsa, jack, and pulse support 32 | services.pipewire = { 33 | enable = true; 34 | pulse.enable = true; 35 | alsa.enable = true; 36 | alsa.support32Bit = true; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /hardware/amd-thinkpad/disable-input-devices.nix: -------------------------------------------------------------------------------- 1 | { self, ... }: { 2 | imports = [ self.nixosModules.disable-input-devices ]; 3 | 4 | # create device paths to disable input devices 5 | programs.disable-input-devices = { 6 | enable = true; 7 | allowedGroups = [ "video" ]; 8 | # Show all event devices: 9 | # $ sudo evtest 10 | # Get information about a device: 11 | # $ udevadm info -a /dev/input/eventXX 12 | # Test by blocking a device: 13 | # $ sudo evtest --grab /dev/input/eventXX 14 | disableDevices = { 15 | # "AT Translated Set 2 keyboard" 16 | # Laptop Keyboard 17 | "thinkpad/keyboard" = { 18 | product = "0001"; 19 | vendor = "0001"; 20 | }; 21 | # "ThinkPad Extra Buttons" 22 | # Laptop Special Function Keys 23 | "thinkpad/extra-buttons" = { 24 | product = "5054"; 25 | vendor = "17aa"; 26 | }; 27 | # "TPPS/2 Elan TrackPoint" 28 | # TrackPoint and Touchpad Buttons 29 | "thinkpad/trackpoint" = { 30 | product = "000a"; 31 | vendor = "0002"; 32 | }; 33 | # "SynPS/2 Synaptics TouchPad" 34 | # Laptop Touchpad 35 | "thinkpad/touchpad" = { 36 | product = "0007"; 37 | vendor = "0002"; 38 | }; 39 | # # "Power Button" 40 | # # Power/Sleep Button 41 | # "thinkpad/power-button" = { 42 | # product = "0001"; 43 | # vendor = "0000"; 44 | # }; 45 | # "Lid Switch" 46 | # Laptop Close Switch 47 | "thinkpad/lid-switch" = { 48 | product = "0005"; 49 | vendor = "0000"; 50 | }; 51 | }; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /hardware/amd-thinkpad/graphics.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, ... }: { 2 | hardware.amdgpu = { 3 | # Prefer `amdgpu` over `radeon`. 4 | legacySupport.enable = true; 5 | # Ensure that AMDGPU is loaded over Radeon. 6 | initrd.enable = true; 7 | # RADV is preferred for performance but `amdvlk` is fallback. 8 | amdvlk.enable = true; 9 | amdvlk.support32Bit.enable = true; 10 | }; 11 | 12 | hardware.graphics = { 13 | enable = true; 14 | enable32Bit = true; 15 | }; 16 | 17 | environment.variables = { 18 | # Ordered. 19 | # 20 | VK_DRIVER_FILES = lib.concatStringsSep ":" [ 21 | "/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json" 22 | "/run/opengl-driver-32/share/vulkan/icd.d/radeon_icd.i686.json" 23 | "/run/opengl-driver/share/vulkan/icd.d/amd_icd64.json" 24 | "/run/opengl-driver-32/share/vulkan/icd.d/amd_icd32.json" 25 | ]; 26 | # From Mesa, for Vulkan, alongside `radeonsi` for OpenGL. 27 | # This environment variable can be changed to select `amdvlk`. 28 | AMD_VULKAN_ICD = "RADV"; 29 | # Mesa Gallium driver, OpenGL to Vulkan. Third-layer abstraction. 30 | # MESA_LOADER_DRIVER_OVERRIDE = "zink"; 31 | # Official AMD, directly provides OpenGL. Use RADV for Vulkan. 32 | MESA_LOADER_DRIVER_OVERRIDE = "radeonsi"; 33 | }; 34 | 35 | boot.kernelParams = [ 36 | # Allow the GPU to power down when displays are attached. 37 | "amdgpu.runpm=-2" 38 | ]; 39 | } 40 | -------------------------------------------------------------------------------- /hm-modules/disable-input/common.nix: -------------------------------------------------------------------------------- 1 | _: { 2 | baseName = "disable-input-devices"; 3 | version = "0.0.1"; 4 | src = ./.; 5 | } 6 | -------------------------------------------------------------------------------- /hm-modules/disable-input/disable-devices-notify.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -eux 3 | 4 | toggle_script="$(realpath "$(dirname "$0")")/disable-devices.sh" 5 | 6 | prefix=() 7 | if [ -n "${DISABLE_DEVICES-}" ]; then 8 | prefix=("DISABLE_DEVICES='$DISABLE_DEVICES'") 9 | fi 10 | 11 | : "${DISABLE_DELAY:=1}" 12 | : "${DISABLE_DURATION:=30}" 13 | : "${NOTIFICATION_COUNTDOWN:=28}" 14 | : "${NOTIFICATION_TIMEOUT:=2000}" 15 | : "${NOTIFICATION_TEXT_SIZE:=x-large}" 16 | : "${NOTIFICATION_ICON_CATEGORY:=devices}" 17 | : "${NOTIFICATION_ICON_NAME:=input-keyboard}" 18 | : "${NOTIFICATION_URGENCY:=critical}" 19 | : "${NOTIFICATION_TITLE:=Input/Keyboard}" 20 | __NOTIFICATION_COUNTDOWN_TIMEOUT=2000 21 | 22 | sleep "$(bc <<< "scale=3; $DISABLE_DELAY / 1000")" 23 | 24 | IFS=' ' read -ra evtest_pids <<< "$(sudo "${prefix[@]}" "$toggle_script" disable)" 25 | device_count=${#evtest_pids[@]} 26 | 27 | notify-send \ 28 | "$NOTIFICATION_TITLE" \ 29 | "Disabled\\n$device_count devices" \ 30 | -u $NOTIFICATION_URGENCY \ 31 | -t $NOTIFICATION_TIMEOUT \ 32 | -c $NOTIFICATION_ICON_CATEGORY \ 33 | -i $NOTIFICATION_ICON_NAME \ 34 | -h string:synchronous:disable-keyboard 35 | 36 | sleep $((DISABLE_DURATION - NOTIFICATION_COUNTDOWN)) 37 | 38 | for i in $(seq 0 $NOTIFICATION_COUNTDOWN); do 39 | i=$((NOTIFICATION_COUNTDOWN - i)) 40 | notify-send \ 41 | "$NOTIFICATION_TITLE" \ 42 | "Enabling $device_count devices in $i seconds" \ 43 | -u $NOTIFICATION_URGENCY \ 44 | -t $__NOTIFICATION_COUNTDOWN_TIMEOUT \ 45 | -c $NOTIFICATION_ICON_CATEGORY \ 46 | -i $NOTIFICATION_ICON_NAME \ 47 | -h int:value:$((100 * i / NOTIFICATION_COUNTDOWN)) \ 48 | -h string:synchronous:disable-keyboard 49 | sleep 1 50 | done 51 | 52 | sudo "${prefix[@]}" "$toggle_script" release 53 | 54 | notify-send \ 55 | "$NOTIFICATION_TITLE" \ 56 | "Enabled\\n$device_count devices" \ 57 | -u $NOTIFICATION_URGENCY \ 58 | -t $NOTIFICATION_TIMEOUT \ 59 | -c $NOTIFICATION_ICON_CATEGORY \ 60 | -i $NOTIFICATION_ICON_NAME \ 61 | -h string:synchronous:disable-keyboard 62 | -------------------------------------------------------------------------------- /hm-modules/idlehack.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | let 3 | inherit (lib) types; 4 | cfg = config.services.idlehack; 5 | in { 6 | options = { 7 | services.idlehack = { 8 | enable = lib.mkEnableOption cfg.package.meta.description; 9 | package = lib.mkOption { 10 | type = types.package; 11 | default = pkgs.idlehack; 12 | example = lib.literalExpression '' 13 | pkgs.idlehack 14 | ''; 15 | description = '' 16 | The package to use for the *idlehack* binary. 17 | ''; 18 | }; 19 | }; 20 | }; 21 | 22 | config = lib.mkIf cfg.enable { 23 | home.packages = [ cfg.package ]; 24 | 25 | systemd.user.services.idlehack = { 26 | Unit = { 27 | Description = cfg.package.meta.description; 28 | After = [ "syslog.target" ]; 29 | }; 30 | Service = { 31 | Type = "simple"; 32 | KillMode = "process"; 33 | Environment = "PATH=${lib.makeBinPath [ pkgs.systemd cfg.package ]}"; 34 | ExecStart = lib.getExe cfg.package; 35 | Restart = "on-failure"; 36 | RestartSec = 5; 37 | }; 38 | Install = { WantedBy = [ "graphical-session.target" ]; }; 39 | }; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /hm-modules/keepassxc.nix: -------------------------------------------------------------------------------- 1 | # TODO maybe? 2 | # 3 | # 4 | { config, lib, pkgs, ... }: 5 | let 6 | inherit (lib) types; 7 | 8 | service = config.services.keepassxc; 9 | program = config.programs.keepassxc; 10 | 11 | iniFormat = pkgs.formats.ini { }; 12 | in { 13 | options = { 14 | services.keepassxc = { 15 | enable = lib.mkEnableOption "KeePassXC Service"; 16 | 17 | package = lib.mkOption { 18 | type = types.package; 19 | description = '' 20 | Uses the program configuration's package by default. 21 | ''; 22 | defaultText = '' 23 | {option}`config.programs.keepassxc.package` 24 | ''; 25 | }; 26 | }; 27 | 28 | programs.keepassxc = { 29 | enable = lib.mkEnableOption '' 30 | Whether to install KeePassXC. 31 | ''; 32 | 33 | package = lib.mkPackageOption pkgs "keepassxc" { }; 34 | 35 | settings = lib.mkOption { 36 | type = iniFormat.type; 37 | default = { }; 38 | description = '' 39 | Settings to write in INI format to {file}`~/.config/keepassxc/keepassxc.ini`. 40 | ''; 41 | }; 42 | 43 | browserIntegration.firefox = lib.mkEnableOption '' 44 | Create the native messaging manifest in {path}`$HOME/.mozilla/native-messaging-hosts`, 45 | required for integration with the browser extension. 46 | 47 | Enabling this option is required if you use declarative {option}`settings`. 48 | 49 | Note that this also requires `Browser.Enabled = true` in {option}`settings`, 50 | or enable it via the GUI. 51 | ''; 52 | }; 53 | }; 54 | 55 | config = lib.mkMerge [ 56 | (lib.mkIf program.enable { home.packages = [ program.package ]; }) 57 | 58 | { services.keepassxc.package = lib.mkDefault program.package; } 59 | 60 | (lib.mkIf (program.enable && program.settings != { }) { 61 | xdg.configFile."keepassxc/keepassxc.ini".source = 62 | iniFormat.generate "keepassxc.ini" program.settings; 63 | }) 64 | 65 | (lib.mkIf ((program.enable || service.enable) 66 | && program.browserIntegration.firefox) { 67 | home.file.".mozilla/native-messaging-hosts/org.keepassxc.keepassxc_browser.json".text = 68 | builtins.toJSON { 69 | allowed_extensions = [ "keepassxc-browser@keepassxc.org" ]; 70 | description = "KeePassXC integration with native messaging support"; 71 | name = "org.keepassxc.keepassxc_browser"; 72 | path = lib.getExe' service.package "keepassxc-proxy"; 73 | type = "stdio"; 74 | }; 75 | }) 76 | 77 | (lib.mkIf service.enable { 78 | systemd.user.services.keepassxc = { 79 | Unit = { 80 | Description = service.package.meta.description; 81 | After = [ "graphical-session.target" ]; 82 | }; 83 | Service = { 84 | Type = "simple"; 85 | KillMode = "process"; 86 | ExecStart = lib.getExe' service.package "keepassxc"; 87 | Restart = "on-failure"; 88 | RestartSec = 5; 89 | }; 90 | Install = { WantedBy = [ "graphical-session.target" ]; }; 91 | }; 92 | }) 93 | ]; 94 | } 95 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/README: -------------------------------------------------------------------------------- 1 | Icons from Google Material Design Icons 2 | 3 | 4 | 5 | Provided under the Apache License 2.0 6 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/rounded-white/mic_off_white_36dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/rounded-white/mic_white_36dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/rounded-white/volume_down_white_36dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/rounded-white/volume_off_white_36dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/icons/rounded-white/volume_up_white_36dp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hm-modules/osd-functions/package.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv, makeBinaryWrapper, bash, coreutils, gawk, gnugrep, bc, libnotify 2 | , wireplumber, scriptOptions ? { }, }: 3 | let 4 | scriptOptions' = (lib.recursiveUpdate { 5 | timeout = 700; 6 | urgency = "low"; 7 | mainTextSize = "x-large"; 8 | iconsDirectory = "$out/share/icons/rounded-white"; 9 | outputTitle = "Default Audio Output"; 10 | inputTitle = "Default Audio Input"; 11 | outputDevice = "@DEFAULT_AUDIO_SINK@"; 12 | inputDevice = "@DEFAULT_AUDIO_SOURCE@"; 13 | outputMaximum = 1.0; 14 | colors = { 15 | normalHighlight = "#00ff00"; 16 | warningHighlight = "#ff0000"; 17 | }; 18 | icons = { 19 | outputDisable = "volume_off_white_36dp.svg"; 20 | outputEnable = "volume_up_white_36dp.svg"; 21 | outputIncrease = "volume_up_white_36dp.svg"; 22 | outputDecrease = "volume_down_white_36dp.svg"; 23 | inputDisable = "mic_off_white_36dp.svg"; 24 | inputEnable = "mic_white_36dp.svg"; 25 | }; 26 | } scriptOptions); 27 | in stdenv.mkDerivation { 28 | pname = "osd-functions"; 29 | version = "0.0.1"; 30 | 31 | strictDeps = true; 32 | 33 | src = ./.; 34 | 35 | nativeBuildInputs = [ makeBinaryWrapper ]; 36 | buildInputs = [ bash ]; 37 | 38 | installPhase = '' 39 | runHook preInstall 40 | 41 | install -Dm755 ./functions.sh $out/bin/functions 42 | mkdir -p $out/share 43 | cp -r ./icons -t $out/share 44 | 45 | runHook postInstall 46 | ''; 47 | 48 | postFixup = '' 49 | wrapProgram $out/bin/functions \ 50 | --set TIMEOUT \ 51 | '${toString scriptOptions'.timeout}' \ 52 | --set URGENCY \ 53 | '${scriptOptions'.urgency}' \ 54 | --set MAIN_TEXT_SIZE \ 55 | '${scriptOptions'.mainTextSize}' \ 56 | --set ICONS_DIRECTORY \ 57 | "${scriptOptions'.iconsDirectory}" \ 58 | --set OUTPUT_TITLE \ 59 | '${scriptOptions'.outputTitle}' \ 60 | --set INPUT_TITLE \ 61 | '${scriptOptions'.inputTitle}' \ 62 | --set OUTPUT_DEVICE \ 63 | '${scriptOptions'.outputDevice}' \ 64 | --set INPUT_DEVICE \ 65 | '${scriptOptions'.inputDevice}' \ 66 | --set OUTPUT_MAXIMUM \ 67 | '${toString scriptOptions'.outputMaximum}' \ 68 | --set NORMAL_HIGHLIGHT_COLOR \ 69 | '${toString scriptOptions'.colors.normalHighlight}' \ 70 | --set WARNING_HIGHLIGHT_COLOR \ 71 | '${toString scriptOptions'.colors.warningHighlight}' \ 72 | --set OUTPUT_DISABLE_ICON \ 73 | '${scriptOptions'.icons.outputDisable}' \ 74 | --set OUTPUT_ENABLE_ICON \ 75 | '${scriptOptions'.icons.outputEnable}' \ 76 | --set OUTPUT_INCREASE_ICON \ 77 | '${scriptOptions'.icons.outputIncrease}' \ 78 | --set OUTPUT_DECREASE_ICON \ 79 | '${scriptOptions'.icons.outputDecrease}' \ 80 | --set INPUT_DISABLE_ICON \ 81 | '${scriptOptions'.icons.inputDisable}' \ 82 | --set INPUT_ENABLE_ICON \ 83 | '${scriptOptions'.icons.inputEnable}' \ 84 | --set PATH \ 85 | '${lib.makeBinPath [ coreutils gawk gnugrep bc libnotify wireplumber ]}' 86 | ''; 87 | 88 | meta = { 89 | description = '' 90 | Shell script to execute actions when function keys are triggered 91 | ''; 92 | license = lib.licenses.mit; 93 | platforms = lib.platforms.linux; 94 | mainProgram = "functions"; 95 | maintainers = with lib.maintainers; [ spikespaz ]; 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /hm-modules/randbg/default.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | let 3 | description = "Customizable wallpaper randomization service"; 4 | cfg = config.services.randbg; 5 | inherit (lib) types; 6 | in { 7 | options = { 8 | services.randbg = { 9 | enable = lib.mkEnableOption description; 10 | 11 | directory = lib.mkOption { 12 | type = types.str; 13 | default = "${config.home.homeDirectory}/Pictures/Wallpapers"; 14 | defaultText = lib.literalExpression '' 15 | ${config.home.homeDirectory}/Pictures/Wallpapers 16 | ''; 17 | description = '' 18 | The path to the directory where your desired wallpapers are stored. 19 | This directory will be recursed when selecting new images, and 20 | valid extensions are `*.png`, `*.jpg`, and `*.jpeg`. 21 | ''; 22 | }; 23 | 24 | interval = lib.mkOption { 25 | type = types.ints.positive; 26 | default = 30 * 60; 27 | defaultText = "`30 * 60` seconds"; 28 | description = '' 29 | The time interval between wallpaper cycles, in seconds. 30 | ''; 31 | }; 32 | 33 | chance = lib.mkOption { 34 | type = types.ints.between 1 100; 35 | default = 25; 36 | defaultText = "`25` percent chance"; 37 | description = '' 38 | The percentage chance that the wallpaper will change 39 | after each interval. 40 | ''; 41 | }; 42 | 43 | swaybg.color = lib.mkOption { 44 | type = types.strMatching "^(#[a-fA-F0-9]{6})"; 45 | default = "#121212"; 46 | description = '' 47 | The RGBA color value to use as a background color (behind the mage). 48 | ''; 49 | }; 50 | 51 | swaybg.mode = lib.mkOption { 52 | type = 53 | types.enum [ "stretch" "fill" "fit" "center" "tile" "solid_color" ]; 54 | default = "fit"; 55 | description = '' 56 | The mode to use when fitting the image to the display. 57 | 58 | See `swaybg(1)` for more information. 59 | ''; 60 | }; 61 | 62 | wantedBy = lib.mkOption { 63 | type = types.listOf types.str; 64 | default = [ "sway-session.target" "hyprland-session.target" ]; 65 | defaultText = lib.literalExpression '' 66 | [ "hyprland-session.target" ] 67 | ''; 68 | description = '' 69 | The value of `Install.WantedBy` in the generated *systemd* 70 | service unit. Use this option to make your window manager's 71 | target unit trigger this service when it starts. 72 | ''; 73 | }; 74 | }; 75 | }; 76 | 77 | config = lib.mkIf cfg.enable { 78 | systemd.user.services.random-wallpaper = { 79 | Unit = { 80 | Description = description; 81 | PartOf = "graphical-session.target"; 82 | }; 83 | Service = { 84 | Type = "notify"; 85 | NotifyAccess = "all"; # because of a bug? 86 | ExecStart = lib.concatStringsSep " " [ 87 | (lib.wrapShellScript pkgs ./wallpaper.sh 88 | (with pkgs; [ systemd coreutils procps gawk findutils swaybg ])) 89 | "-i ${toString cfg.interval}" 90 | "-c ${toString cfg.chance}" 91 | "-d '${cfg.directory}'" 92 | "--" 93 | "-c ${cfg.swaybg.color}" 94 | "-m ${cfg.swaybg.mode}" 95 | ]; 96 | Restart = "on-failure"; 97 | RestartSec = 5; 98 | }; 99 | Install.WantedBy = cfg.wantedBy; 100 | }; 101 | }; 102 | } 103 | -------------------------------------------------------------------------------- /hm-modules/randbg/wallpaper.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | set -eux -o pipefail 3 | 4 | interval= 5 | chance= 6 | img_dir= 7 | passthru_args=() 8 | 9 | while [[ $# -gt 0 ]]; do 10 | case "$1" in 11 | -i) 12 | interval="$2" 13 | shift 2 14 | ;; 15 | -c) 16 | chance="$2" 17 | shift 2 18 | ;; 19 | -d) 20 | img_dir="$2" 21 | shift 2 22 | ;; 23 | --) 24 | shift 25 | passthru_args=("$@") 26 | break 27 | ;; 28 | *) 29 | echo "Error: unknown argument: $1" 30 | exit 99 31 | esac 32 | done 33 | 34 | if [ -z "$interval" ] || [ "$interval" -ne "$interval" ]; then 35 | echo 'Error: value for argument -i was not a number!' 36 | exit 10 37 | fi 38 | if [ -z "$chance" ] || [ "$chance" -ne "$chance" ]; then 39 | echo 'Error: value for argument -c was not a number!' 40 | exit 11 41 | fi 42 | if [ ! -d "$img_dir" ]; then 43 | echo 'Error: value for argument -d was not a directory!' 44 | exit 12 45 | fi 46 | 47 | echo "Interval = $interval" 48 | echo "Chance = $chance" 49 | echo "Image Directory = $img_dir" 50 | echo "User = $USER" 51 | echo "Passthrough Argments = ${passthru_args[*]}" 52 | session_id=$(ps -o sess= -p $$ | tr -d '[:space:]') 53 | echo "Session ID = $session_id" 54 | 55 | set_img() { 56 | old_pids="$( 57 | ps -o pid,sess,cmd -u "$USER" \ 58 | | awk -v sess="$session_id" '$2 == sess && $0 ~ /swaybg/ {print $1}' 59 | )" 60 | if [ -z "$old_pids" ]; then 61 | echo "Found old swaybg PIDs: $old_pids" 62 | fi 63 | 64 | echo 'Selecting new image...' 65 | new_img="$( 66 | find "$img_dir" \ 67 | -type f \ 68 | -name '*.png' -o -name '*.jpg' -o -name '*.jpeg' \ 69 | | shuf -n1 70 | )" 71 | if [ ! -f "$new_img" ]; then 72 | echo 'Error: could not find the next image!' 73 | exit 20 74 | fi 75 | echo "Selected new image: $new_img" 76 | 77 | if [ "$new_img" = "${old_img-}" ]; then 78 | echo 'Duplicate, re-rolling...' 79 | set_img 80 | else 81 | echo 'Setting the selected image...' 82 | swaybg "${passthru_args[@]}" -i "$new_img" -m fill & 83 | 84 | if [ -n "${old_pids-}" ]; then 85 | sleep 10 # this is huge because of huge images 86 | echo 'Killing old swaybg PIDs...' 87 | # shellcheck disable=SC2086 88 | kill -s 9 $old_pids || : 89 | fi 90 | 91 | old_img="$new_img" 92 | fi 93 | } 94 | 95 | echo 'Setting the first image!' 96 | set_img 97 | if [ -n "${NOTIFY_SOCKET-}" ]; then 98 | if systemd-notify --ready; then 99 | echo "Notified systemd that this unit is ready." 100 | else 101 | echo 'Error: failed to notify systemd that we are ready!' 102 | exit 30 103 | fi 104 | fi 105 | sleep "$interval" 106 | 107 | while true; do 108 | echo 'Deciding if the wallpaper should be changed...' 109 | if [ "$(shuf -i0-100 -n1)" -le "$chance" ]; then 110 | echo 'Lucky roll, resetting!' 111 | set_img 112 | else 113 | echo 'Entropy rejects you.' 114 | fi 115 | 116 | echo 'Finished, waiting for next loop...' 117 | sleep "$interval" 118 | done 119 | -------------------------------------------------------------------------------- /hm-modules/webcord.nix: -------------------------------------------------------------------------------- 1 | # Adapted from Fufexan's webcord-flake: 2 | # 3 | # 4 | # I am appointing myself the new maintainer, 5 | # as the original author no longer uses WebCord. 6 | # 7 | # Both `webcord` and `webcord-vencord` packages are 8 | # maintained in Nixpkgs, so those will be used from now on 9 | # instead of the original `dream2nix` one. 10 | # 11 | { config, pkgs, lib, ... }: 12 | let 13 | inherit (lib) types; 14 | cfg = config.programs.webcord; 15 | in { 16 | options = { 17 | programs.webcord = { 18 | enable = lib.mkEnableOption cfg.package.meta.description; 19 | 20 | package = lib.mkPackageOptionMD pkgs [ "webcord" ] { 21 | example = [ "webcord-vencord" ]; 22 | }; 23 | 24 | themes = lib.mkOption { 25 | type = types.attrsOf types.path; 26 | default = { }; 27 | description = '' 28 | An attribute set of themes, where each key is the name of the 29 | theme when linked into {path}`$XDG_CONFIG_HOME/WebCord/Themes`, 30 | and the value is the file path of the CSS source. 31 | 32 | *This will need to change once the 33 | [feature](https://github.com/SpacingBat3/WebCord/blob/master/docs/Features.md#1-custom-discord-styles) 34 | is stabilized.* 35 | ''; 36 | example = lib.literalExpression '' 37 | let 38 | repo = pkgs.fetchFromGitHub { 39 | owner = "mwittrien"; 40 | repo = "BetterDiscordAddons"; 41 | rev = "8627bb7f71c296d9e05d82538d3af8f739f131dc"; 42 | sha256 = "sha256-Dn6igqL0GvaOcTFZOtQOxuk0ikrWxyDZ41tNsJXJAxc="; 43 | }; 44 | 45 | themes = { 46 | discord-recolor = "''${repo}/Themes/DiscordRecolor/DiscordRecolor.theme.css"; 47 | settings-modal = "''${repo}/Themes/SettingsModal/SettingsModal.theme.css"; 48 | }; 49 | in { 50 | DiscordRecolor = themes.discord-recolor; 51 | SettingsModal = themes.settings-modal; 52 | } 53 | ''; 54 | }; 55 | 56 | deleteThemes = lib.mkEnableOption '' 57 | Whether to enable the DAG entry to delete files in the `Themes` 58 | directory before creating new links. 59 | 60 | Note that this is not necessary to mitigate the issue with WebCord 61 | not cleaning up, because all symlinks created by Nix will be re-created 62 | upon a generation switch. 63 | 64 | Only enable this if for some reason you don't want to be able to add 65 | files to the `Themes` directory manually. 66 | 67 | **The `Themes` directory contents will be permanently deleted** 68 | when activating a new generation! 69 | ''; 70 | }; 71 | }; 72 | 73 | config = lib.mkIf cfg.enable (lib.mkMerge [ 74 | # add the package 75 | { 76 | home.packages = [ cfg.package ]; 77 | } 78 | 79 | # handle the themes if any 80 | (lib.mkIf (cfg.themes != { }) { 81 | # for every theme provided, create a symlink in the conf dir 82 | # to the path provided (see themes opt description) 83 | xdg.configFile = lib.mapAttrs' (name: source: { 84 | name = "WebCord/Themes/${name}"; 85 | value = { inherit source; }; 86 | }) cfg.themes; 87 | }) 88 | 89 | # add a DAG entry to remove the themes that are not managed 90 | (lib.mkIf (cfg.deleteThemes) { 91 | home.activation = { 92 | rmWebCordThemes = lib.hm.dag.entryBefore [ "linkGeneration" ] '' 93 | $DRY_RUN_CMD rm -rf $VERBOSE_ARG \ 94 | ${config.xdg.configHome}/WebCord/Themes/* 95 | ''; 96 | }; 97 | }) 98 | ]); 99 | } 100 | -------------------------------------------------------------------------------- /hm-modules/zsh/integrations.nix: -------------------------------------------------------------------------------- 1 | { config, lib, ... }: 2 | let cfg = config.programs.zsh.alt; 3 | in { 4 | options = { 5 | programs.zsh.alt = { 6 | enableIntegrations = lib.mkEnableOption '' 7 | Enable integrations from other Home Manager modules. 8 | ''; 9 | 10 | enableAliases = lib.mkEnableOption '' 11 | Enable aliases defined by other Home Manager modules. 12 | ''; 13 | }; 14 | }; 15 | 16 | config = lib.mkIf cfg.enable (lib.mkMerge [ 17 | (lib.mkIf cfg.enableIntegrations { 18 | programs.zsh.alt.zshrc.postInit = '' 19 | ### HOME MANAGER EXTRA INITIALIZATION ### 20 | 21 | ${config.programs.zsh.initExtra} 22 | 23 | ### END ### 24 | ''; 25 | }) 26 | 27 | (lib.mkIf cfg.enableAliases { 28 | programs.zsh.alt.zshrc.main = lib.mkAfter (lib.concatStringsSep "\n" 29 | (builtins.concatLists [ 30 | (lib.singleton '' 31 | ### HOME MANAGER ALIASES ### 32 | '') 33 | (lib.mapAttrsToList (k: v: "alias ${k}=${lib.escapeShellArg v}") 34 | config.programs.zsh.shellAliases) 35 | (lib.mapAttrsToList (k: v: "alias -g ${k}=${lib.escapeShellArg v}") 36 | config.programs.zsh.shellGlobalAliases) 37 | (lib.singleton '' 38 | 39 | ### END ###'') 40 | ])); 41 | }) 42 | ]); 43 | } 44 | -------------------------------------------------------------------------------- /hosts/intrepid/default.nix: -------------------------------------------------------------------------------- 1 | args@{ self, tree, lib, inputs }: 2 | lib.bird.mkHost args { 3 | hostPlatform.system = "x86_64-linux"; 4 | nixpkgs = inputs.nixpkgs-unstable; 5 | nixpkgsArgs.config.allowUnfree = true; 6 | modules = with tree.hosts; [ 7 | shared.amd-thinkpad.hardware 8 | shared.amd-thinkpad.bootloader 9 | # shared.amd-thinkpad.plymouth 10 | shared.amd-thinkpad.user-desktop 11 | 12 | shared.touchpad-fix 13 | shared.greetd-hyprland 14 | # shared.gamemode 15 | shared.run-game 16 | shared.packages 17 | shared.nix-registry 18 | shared.pia-openvpn 19 | shared.nixbuild 20 | 21 | ./misc.nix 22 | ./filesystems.nix 23 | ./powerplan.nix 24 | ]; 25 | overlays = [ 26 | # flake packages 27 | self.overlays.default 28 | # override packages with an unfree license 29 | self.overlays.allowUnfree 30 | # window manager 31 | inputs.hyprnix.overlays.default 32 | # other packages 33 | inputs.slight.overlays.default 34 | inputs.ragenix.overlays.default 35 | ]; 36 | } 37 | -------------------------------------------------------------------------------- /hosts/intrepid/filesystems.nix: -------------------------------------------------------------------------------- 1 | # This module is responsible for configuring everything required 2 | # to use the partition scheme defined by `partition.sh`, 3 | # as well as making it bootable. Note that the bootloader itself 4 | # should still be configured mostly elsewhere--at least the options 5 | # that have the potential to vary from across systems. 6 | # 7 | # Further reading: 8 | # - 9 | # - 10 | { config, lib, pkgs, ... }: 11 | let 12 | rootPool = "intrepid"; 13 | bootLabel = "INTRPD"; 14 | 15 | # function to easily duplicate a zfs automount scheme 16 | zfsAuto = device: { 17 | inherit device; 18 | fsType = "zfs"; 19 | options = [ "zfsutil" "X-mount.mkdir" ]; 20 | }; 21 | in { 22 | # we never want to allow nix to create hard-links 23 | # because the filesystem takes care of that 24 | nix.settings.auto-optimise-store = false; 25 | 26 | fileSystems = { 27 | "/" = zfsAuto "${rootPool}/root"; 28 | "/var/lib" = zfsAuto "${rootPool}/var/lib"; 29 | "/var/log" = zfsAuto "${rootPool}/var/log"; 30 | "/var/cache" = zfsAuto "${rootPool}/var/cache"; 31 | "/nix" = zfsAuto "${rootPool}/nix"; 32 | "/home" = zfsAuto "${rootPool}/home"; 33 | 34 | "/boot" = { 35 | device = "/dev/disk/by-label/${bootLabel}"; 36 | fsType = "vfat"; 37 | }; 38 | }; 39 | 40 | swapDevices = [{ label = "swap"; }]; 41 | 42 | # Only configure the necessary prerequisite boot parameters. 43 | boot = { 44 | # for some reason not set automatically 45 | # docs say this should be set auto when "" 46 | resumeDevice = "/dev/disk/by-label/swap"; 47 | 48 | supportedFilesystems = [ "zfs" ]; 49 | kernelModules = [ "zfs" ]; 50 | 51 | zfs = { 52 | forceImportAll = false; 53 | forceImportRoot = false; 54 | allowHibernation = true; 55 | }; 56 | }; 57 | 58 | # Maintenance, this should be the same across every computer 59 | # that uses this module. 60 | services.zfs = { 61 | trim.enable = true; 62 | trim.interval = "weekly"; 63 | 64 | autoScrub.enable = true; 65 | autoScrub.pools = [ rootPool ]; 66 | autoScrub.interval = "weekly"; 67 | }; 68 | 69 | services.fstrim.enable = lib.mkForce false; 70 | } 71 | -------------------------------------------------------------------------------- /hosts/odyssey/cpu-frequency.nix: -------------------------------------------------------------------------------- 1 | { config, lib, ... }: { 2 | # imports = [ self.nixosModules.amdctl ]; 3 | 4 | environment.systemPackages = [ 5 | # *cpupower* could be in `packages.nix`, but it's a common diagnostic 6 | # tool that should probably come along with the config that follows. 7 | # 8 | config.boot.kernelPackages.cpupower 9 | ]; 10 | 11 | boot.kernelParams = [ 12 | # Required reading: 13 | # 14 | # 15 | # 16 | # Note that the EPP driver succeeds TLP's scheduler switching 17 | # and makes it obsolete. Disable that function of TLP. 18 | "amd_pstate=active" 19 | ]; 20 | 21 | # This CPU (R7 8740U) has these energy performance preferences: 22 | # default, performance, balance_performance, balance_power, power. 23 | # 24 | # Based on Phoronix' results: 25 | # 26 | # 27 | # I have decided on scheduler `powersave` and EPP `balance_performance`. 28 | # I will also consider `powersave` and ` balance_power` once we know more. 29 | # 30 | # I assume `balance_performance` means to choose to balance 31 | # performance over power efficiency, 32 | # and `balance_power` chooses efficiency over performance. 33 | services.udev.extraRules = let 34 | num_cpus = 16; 35 | scaling_governor = "powersave"; 36 | energy_performance_preference = "balance_power"; 37 | in lib.concatLines (lib.genList (cpu: '' 38 | KERNEL=="cpu${toString cpu}", SUBSYSTEM=="cpu", ATTR{cpufreq/scaling_governor}="${scaling_governor}" 39 | KERNEL=="cpu${toString cpu}", SUBSYSTEM=="cpu", ATTR{cpufreq/energy_performance_preference}="${energy_performance_preference}" 40 | '') num_cpus); 41 | 42 | # Now TLP can be used to control this automatically while 43 | # the system is running. The values set above should be mostly fine, 44 | # but AC/battery profiles are further constrained below. 45 | # 46 | # The driver mode is `guided` so that we can control the frequencies. 47 | services.tlp.enable = false; 48 | # Documentation: 49 | # 50 | services.tlp.settings = let 51 | MHz = x: x * 1000; 52 | 53 | # These values can be discovered by register files in *sysfs*. 54 | max_freq = MHz 5132; 55 | lowest_nonlinear_freq = MHz 1099; 56 | 57 | # Fraction of the frequency range where power consumption is high. 58 | freq_deficit_bat = 0.2; # approximately 3.2 GHz 59 | in { 60 | TLP_ENABLE = 1; 61 | # TLP_WARN_LEVEL = 3; 62 | TLP_DEFAULT_MODE = "BAT"; 63 | 64 | ## Processor 65 | 66 | CPU_BOOST_ON_AC = 1; 67 | CPU_BOOST_ON_BAT = 0; 68 | 69 | CPU_DRIVER_OPMODE_ON_AC = "guided"; 70 | CPU_SCALING_GOVERNOR_ON_AC = "schedutil"; 71 | CPU_ENERGY_PERF_POLICY_ON_AC = "balance_performance"; 72 | 73 | CPU_SCALING_MIN_FREQ_ON_AC = 0; 74 | CPU_SCALING_MAX_FREQ_ON_AC = max_freq; 75 | 76 | CPU_DRIVER_OPMODE_ON_BAT = "guided"; 77 | CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; 78 | CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power"; 79 | 80 | CPU_SCALING_MIN_FREQ_ON_BAT = 0; 81 | CPU_SCALING_MAX_FREQ_ON_BAT = max_freq - (builtins.floor 82 | ((max_freq - lowest_nonlinear_freq) * freq_deficit_bat)); 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /hosts/odyssey/default.nix: -------------------------------------------------------------------------------- 1 | args@{ self, tree, lib, inputs }: 2 | lib.bird.mkHost args { 3 | hostPlatform = { 4 | system = "x86_64-linux"; 5 | } // lib.systems.architectures.featureSupport "znver4"; 6 | nixpkgs = inputs.nixpkgs-unstable; 7 | nixpkgsArgs.config.allowUnfree = true; 8 | modules = 9 | # 10 | with self.nixosModules; 11 | with tree.hosts; [ 12 | hardware.amd-thinkpad.common 13 | hardware.amd-thinkpad.bootloader 14 | hardware.amd-thinkpad.graphics 15 | hardware.amd-thinkpad.airplane-mode 16 | 17 | # shared.amd-thinkpad.plymouth 18 | 19 | shared.touchpad-fix 20 | # shared.gamemode 21 | shared.run-game 22 | shared.packages 23 | shared.nix-registry 24 | shared.pia-openvpn 25 | # shared.nixbuild 26 | shared.user-sessions 27 | shared.peripherals 28 | 29 | ./misc.nix 30 | ./packages.nix 31 | ./filesystems.nix 32 | ./cpu-frequency.nix 33 | ./powerplan.nix 34 | ]; 35 | overlays = [ 36 | # this flake's lib 37 | self.overlays.lib 38 | # flake packages 39 | self.overlays.default 40 | # override packages with an unfree license 41 | self.overlays.allowUnfree 42 | # window manager 43 | inputs.hyprnix.overlays.default 44 | # override certain packages to be fetchable in binary caches 45 | self.overlays.hacks.nixpkgs-config-exceptions 46 | # other packages 47 | inputs.slight.overlays.default 48 | inputs.ragenix.overlays.default 49 | ]; 50 | } 51 | -------------------------------------------------------------------------------- /hosts/odyssey/filesystems.nix: -------------------------------------------------------------------------------- 1 | # This module is responsible for configuring everything required 2 | # to use the partition scheme defined by `partition.sh`, 3 | # as well as making it bootable. Note that the bootloader itself 4 | # should still be configured mostly elsewhere--at least the options 5 | # that have the potential to vary from across systems. 6 | # 7 | # Further reading: 8 | # - 9 | # - 10 | { config, lib, pkgs, ... }: 11 | let 12 | rootPool = "odyssey"; 13 | bootLabel = "ODSY"; 14 | 15 | # function to easily duplicate a zfs automount scheme 16 | zfsAuto = device: { 17 | inherit device; 18 | fsType = "zfs"; 19 | options = [ "zfsutil" "X-mount.mkdir" ]; 20 | }; 21 | in { 22 | # we never want to allow nix to create hard-links 23 | # because the filesystem takes care of that 24 | nix.settings.auto-optimise-store = false; 25 | 26 | fileSystems = { 27 | "/" = zfsAuto "${rootPool}/root"; 28 | "/var/lib" = zfsAuto "${rootPool}/var/lib"; 29 | "/var/log" = zfsAuto "${rootPool}/var/log"; 30 | "/var/cache" = zfsAuto "${rootPool}/var/cache"; 31 | "/nix" = zfsAuto "${rootPool}/nix"; 32 | "/home" = zfsAuto "${rootPool}/home"; 33 | 34 | "/boot" = { 35 | device = "/dev/disk/by-label/${bootLabel}"; 36 | fsType = "vfat"; 37 | }; 38 | }; 39 | 40 | swapDevices = [{ label = "swap"; }]; 41 | 42 | # Only configure the necessary prerequisite boot parameters. 43 | boot = { 44 | # tmpfs allocates for files on-demand 45 | tmp.useTmpfs = false; 46 | # this is the upper-limit, not a block 47 | tmp.tmpfsSize = "20G"; 48 | 49 | # for some reason not set automatically 50 | # docs say this should be set auto when "" 51 | resumeDevice = "/dev/disk/by-label/swap"; 52 | 53 | loader.efi.efiSysMountPoint = "/boot"; 54 | 55 | supportedFilesystems = [ "zfs" ]; 56 | kernelModules = [ "zfs" ]; 57 | 58 | zfs = { 59 | forceImportRoot = false; 60 | allowHibernation = true; 61 | }; 62 | }; 63 | 64 | # Maintenance, this should be the same across every computer 65 | # that uses this module. 66 | services.zfs = { 67 | trim.enable = true; 68 | trim.interval = "weekly"; 69 | 70 | autoScrub.enable = true; 71 | autoScrub.pools = [ rootPool ]; 72 | autoScrub.interval = "weekly"; 73 | }; 74 | 75 | services.fstrim.enable = lib.mkForce false; 76 | } 77 | -------------------------------------------------------------------------------- /hosts/odyssey/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: { environment.systemPackages = with pkgs; [ amdctl ]; } 2 | -------------------------------------------------------------------------------- /hosts/odyssey/powerplan.nix: -------------------------------------------------------------------------------- 1 | # Required Reading: 2 | # - 3 | # - `man sleep.conf.d` 4 | # - `man logind.conf` 5 | { ... }: 6 | let 7 | # hours = h: minutes 60 * h; 8 | # minutes = m: seconds 60 * m; 9 | # seconds = s: s; 10 | in { 11 | services.logind = { 12 | lidSwitch = "suspend"; 13 | killUserProcesses = true; 14 | extraConfig = '' 15 | HandlePowerKey=suspend 16 | HandlePowerKeyLongPress=poweroff 17 | HandleLidSwitchExternalPower=suspend 18 | ''; 19 | # IdleAction=suspend-then-hibernate 20 | # IdleActionSec=${toString (minutes 5)} 21 | }; 22 | 23 | # systemd.sleep.extraConfig = '' 24 | # HibernateDelaySec=${toString (hours 1 + minutes 30)} 25 | # ''; 26 | 27 | services.upower = { 28 | enable = true; 29 | percentageLow = 15; 30 | percentageCritical = 7; 31 | percentageAction = 5; 32 | criticalPowerAction = "HybridSleep"; 33 | }; 34 | 35 | services.thinkfan = { 36 | enable = true; 37 | 38 | # 39 | settings = { 40 | sensors = [ 41 | # GPU 42 | { 43 | hwmon = "/sys/class/hwmon"; 44 | name = "amdgpu"; 45 | indices = [ 1 ]; 46 | } 47 | # CPU 48 | { 49 | hwmon = "/sys/class/hwmon"; 50 | name = "k10temp"; 51 | indices = [ 1 ]; 52 | } 53 | # Chassis 54 | { 55 | hwmon = "/sys/class/hwmon"; 56 | name = "thinkpad"; 57 | indices = [ 1 3 6 7 ]; 58 | max_errors = 10; 59 | } 60 | # SSD 61 | { 62 | hwmon = "/sys/class/hwmon"; 63 | name = "nvme"; 64 | indices = [ 1 2 3 ]; 65 | correction = [ (-5) 0 0 ]; 66 | } 67 | # Motherboard 68 | { 69 | hwmon = "/sys/class/hwmon"; 70 | name = "acpitz"; 71 | indices = [ 1 ]; 72 | } 73 | ]; 74 | 75 | fans = [{ tpacpi = "/proc/acpi/ibm/fan"; }]; 76 | 77 | levels = [ 78 | [ 0 0 60 ] 79 | [ 1 58 63 ] 80 | [ 2 61 66 ] 81 | [ 3 64 69 ] 82 | [ 4 67 72 ] 83 | [ 5 70 75 ] 84 | [ 6 73 78 ] 85 | [ 7 76 81 ] 86 | [ "level full-speed" 79 32767 ] 87 | ]; 88 | }; 89 | }; 90 | } 91 | -------------------------------------------------------------------------------- /hosts/shared/amd-thinkpad/plymouth.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | let 3 | # I don't know if this is really needed, but I extrapolated this 4 | # package override from the nixpkgs config. 5 | plymouth = 6 | pkgs.plymouth.override { systemd = config.boot.initrd.systemd.package; }; 7 | in { 8 | # allow plymouth to take over the framebuffer sooner 9 | console.earlySetup = true; 10 | 11 | # make the boot quiet 12 | boot.consoleLogLevel = 3; 13 | boot.initrd.verbose = false; 14 | 15 | boot.kernelParams = [ 16 | # prevent the kernel from blanking plymouth out of the fb 17 | "fbcon=nodefer" 18 | # disable boot logo if any 19 | "logo.nologo" 20 | # tell the kernel to not be verbose 21 | "quiet" 22 | # disable systemd status messages 23 | "rd.systemd.show_status=auto" 24 | # lower the udev log level to show only errors or worse 25 | "rd.udev.log_level=3" 26 | # disable the cursor in vt to get a black screen during intermissions 27 | # TODO turn back on in tty 28 | "vt.global_cursor_default=0" 29 | ]; 30 | 31 | # configure plymouth theme 32 | # 33 | # 34 | boot.plymouth = let theme = "colorful_loop"; 35 | in { 36 | enable = true; 37 | themePackages = [ 38 | (pkgs.adi1090x-plymouth-themes.override { selected_themes = [ theme ]; }) 39 | ]; 40 | inherit theme; 41 | }; 42 | 43 | # make it work with sleep 44 | powerManagement.powerDownCommands = '' 45 | ${lib.getExe plymouth} --show-splash 46 | ''; 47 | powerManagement.resumeCommands = '' 48 | ${lib.getExe plymouth} --quit 49 | ''; 50 | } 51 | -------------------------------------------------------------------------------- /hosts/shared/nix-registry.nix: -------------------------------------------------------------------------------- 1 | # 2 | { lib, inputs, ... }: 3 | lib.pipe inputs [ 4 | (lib.filterAttrs (name: value: value._type == "flake")) 5 | (lib.mapAttrsToList (name: input: { 6 | environment.etc."nix/inputs/${name}".source = input.outPath; 7 | nix.nixPath = [ "${name}=/etc/nix/inputs/${name}" ]; 8 | nix.registry.${name}.flake = input; 9 | })) 10 | lib.mkMerge 11 | ] 12 | -------------------------------------------------------------------------------- /hosts/shared/nixbuild.nix: -------------------------------------------------------------------------------- 1 | # Thank you to for a great build service, 2 | # and for their public service as well. 3 | # 4 | # Must use the user identity for interacting with the shell while building: 5 | # $ ssh -i ~/.ssh/id_ed25519 eu.nixbuild.net shell 6 | # Otherwise, it will use the host key first and be denied if the daemon 7 | # is connected to the remote already using that key. 8 | { lib, pkgs, ... }: 9 | (xs: { imports = xs; }) [ 10 | { 11 | # the publoic key of this host must be added to nixbuild's 12 | # settings using the configuration shell 13 | programs.ssh.extraConfig = '' 14 | Host eu.nixbuild.net 15 | PubkeyAcceptedKeyTypes ssh-ed25519 16 | IdentityFile /etc/ssh/ssh_host_ed25519_key 17 | ''; 18 | 19 | programs.ssh.knownHosts = { 20 | nixbuild = { 21 | hostNames = [ "eu.nixbuild.net" ]; 22 | publicKey = 23 | "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPIQCZc54poJ8vqawd8TraNryQeJnvH1eLpIDgbiqymM"; 24 | }; 25 | }; 26 | 27 | nix = { 28 | # use nixbuild builders for the specified platforms 29 | distributedBuilds = lib.mkDefault true; 30 | buildMachines = let 31 | # nixbuild requires that each system is a separate builder, 32 | # presumably they have dedicated hardware or virtual machines 33 | systems = [ "x86_64-linux" "aarch64-linux" "armv7l-linux" ]; 34 | in map (system: { 35 | hostName = "eu.nixbuild.net"; 36 | supportedFeatures = [ "benchmark" "big-parallel" ]; 37 | maxJobs = 100; # supposedly ignored 38 | inherit system; 39 | }) systems; 40 | # allow the remote to use substituters (set up with the shell) 41 | settings.builders-use-substitutes = true; 42 | # nixbuild is also used as a substituter for this machine, 43 | # in case we need packages before they upload to cachix (intrepid) 44 | settings.extra-substituters = [ "ssh://eu.nixbuild.net" ]; 45 | settings.extra-trusted-public-keys = [ 46 | "nixbuild.net/spikespaz@outlook.com-1:gvbfrV9++PLNx1aSR+hvWJ126Zy5KY/vIfo+zQ3eUOg=" 47 | ]; 48 | }; 49 | } 50 | # this is also my own public cachix instance, 51 | # which nixbuild will upload completed builds to 52 | { 53 | nix.settings = { 54 | extra-substituters = [ "https://intrepid.cachix.org" ]; 55 | extra-trusted-public-keys = [ 56 | "intrepid.cachix.org-1:6K2f96UHKQt9ceQ7o2fYi4TdCY4K5Y1V/MXk1WI8X5o=" 57 | ]; 58 | }; 59 | 60 | # include the cachix CLI as a system package for good measure 61 | environment.systemPackages = [ pkgs.cachix ]; 62 | } 63 | ] 64 | -------------------------------------------------------------------------------- /hosts/shared/packages.nix: -------------------------------------------------------------------------------- 1 | { pkgs, config, ... }: { 2 | programs.nix-ld.enable = true; 3 | programs.nix-ld.libraries = with pkgs; [ dotnet-runtime_8 ]; 4 | 5 | # NOTE: 6 | # You're supposed to add users to the `adbusers` group for 7 | # these rules to work, but it works for me regardless. 8 | # Perhaps these rules work for users in `wheel`? 9 | # 10 | programs.adb.enable = true; 11 | 12 | # Packages which are appropriate for a typical Linux system. 13 | # There should be **no GUI programs** in this list. 14 | environment.systemPackages = with pkgs; [ 15 | ################## 16 | ### ESSENTIALS ### 17 | ################## 18 | 19 | ### MISSING ### 20 | bc 21 | tree 22 | unzip 23 | 24 | ### CLI UTILITIES ### 25 | fastfetch # neofetch but made in c 26 | wget # simple downloader utility 27 | curl # network request utility 28 | p7zip # archive and compression tool 29 | git # version control 30 | zip # archive utility 31 | bat # cat with wings 32 | fzf # fuzzy finder 33 | eza # colored alternative to ls 34 | ripgrep # grep but rust 35 | sd # sed but rust 36 | # tealdear # manpage summaries 37 | 38 | ### CODE EDITORS ### 39 | neovim 40 | 41 | ################ 42 | ### HARDWARE ### 43 | ################ 44 | 45 | ### SYSTEM DEVICES ### 46 | config.boot.kernelPackages.cpupower 47 | v4l-utils # proprietary media hardware and encoding 48 | pciutils # utilities for pci and pcie devices 49 | 50 | ### GRAPHICS TOOLS ### 51 | vulkan-tools 52 | 53 | ### STORAGE DEVICE DRIVERS ### 54 | cryptsetup 55 | ntfs3g 56 | exfatprogs 57 | 58 | ### STORAGE DEVICE TOOLS ### 59 | parted 60 | gptfdisk 61 | e2fsprogs 62 | 63 | ### HARDWARE DIAGNOSTICS ### 64 | glxinfo # graphics information 65 | smartmontools # for drive SMART status 66 | btop # system process monitor 67 | bottom # not top 68 | procs # process viewer 69 | du-dust # du but rust 70 | bandwhich # network monitor 71 | 72 | ### VIRTUALIZATION ### 73 | libguestfs # filesystem driver for vm images 74 | ]; 75 | 76 | # # gui tool for processor management 77 | # programs.corectrl.enable = true; 78 | # # sets the overdrive bit in amdgpu.ppfeaturemask 79 | # programs.corectrl.gpuOverclock.enable = true; 80 | } 81 | -------------------------------------------------------------------------------- /hosts/shared/peripherals.nix: -------------------------------------------------------------------------------- 1 | { self, lib, pkgs, config, ... }: 2 | let 3 | nuphy-udev-rules = pkgs.stdenvNoCC.mkDerivation { 4 | name = "nuphy-udev-rules"; 5 | version = "332710cd961e4cddaa70009a4a559b6e70a66726"; 6 | src = pkgs.fetchFromGitHub { 7 | owner = "Z3R0-CDS"; 8 | repo = "nuphy-linux"; 9 | rev = nuphy-udev-rules.version; 10 | hash = "sha256-8Ss74o9kgTzUhGNvll0GYBvUx6sGvn6Mq5DDFlWHbDs="; 11 | }; 12 | dontBuild = true; 13 | installPhase = '' 14 | runHook preInstall 15 | install -D nuphy.rules $out/lib/udev/rules.d/51-qmk-nuphy.rules 16 | runHook postInstall 17 | ''; 18 | meta = { 19 | homepage = "https://github.com/Z3R0-CDS/nuphy-linux"; 20 | description = "Unofficial udev rules for Nuphy keyboard devices"; 21 | platforms = lib.platforms.linux; 22 | }; 23 | }; 24 | xpadneo-udev-rules = pkgs.stdenvNoCC.mkDerivation { 25 | name = "xpadneo-udev-rules"; 26 | version = config.boot.kernelPackages.xpadneo.version; 27 | src = config.boot.kernelPackages.xpadneo.src; 28 | dontBuild = true; 29 | installPhase = '' 30 | runHook preInstall 31 | install -d $out/lib/udev/rules.d 32 | install -D hid-xpadneo/etc-udev-rules.d/*.rules $out/lib/udev/rules.d 33 | runHook postInstall 34 | ''; 35 | }; 36 | in { 37 | imports = [ self.nixosModules.qmk-devices ]; 38 | 39 | hardware.xpadneo.enable = true; 40 | 41 | hardware.keyboard.qmk.enable = true; 42 | 43 | services.udev.packages = [ 44 | # udev rules from `pkgs.via` are too permissive 45 | nuphy-udev-rules 46 | # There are conflicts with QMK, which the udev rules will resolve. 47 | # Besides that, the `xpadneo` NixOS module doesn't add them at all. 48 | xpadneo-udev-rules 49 | ]; 50 | 51 | # The `productId` changed after 52 | hardware.keyboard.qmk.extraDevices = [{ 53 | name = "NuPhy Air75 V2.1"; 54 | vendorId = "19f5"; 55 | productId = "3246"; 56 | }]; 57 | } 58 | -------------------------------------------------------------------------------- /hosts/shared/pia-openvpn.nix: -------------------------------------------------------------------------------- 1 | { self, config, pkgs, lib, ... }: 2 | let 3 | authUserPass = config.age.secrets.pia-user-pass.path; 4 | updateResolvConf = true; 5 | 6 | src = pkgs.fetchzip { 7 | stripRoot = false; 8 | url = "https://www.privateinternetaccess.com/openvpn/openvpn.zip"; 9 | hash = "sha256-ZA8RS6eIjMVQfBt+9hYyhaq8LByy5oJaO9Ed+x8KtW8="; 10 | }; 11 | 12 | configs = lib.pipe src.outPath [ 13 | builtins.readDir 14 | (lib.mapAttrs' (file: type: 15 | let 16 | match = builtins.match "(.+)\\.ovpn" file; 17 | name = if type == "regular" && match != null then 18 | builtins.elemAt match 0 19 | else 20 | "_"; 21 | value = if name != null then { 22 | inherit authUserPass updateResolvConf; 23 | autoStart = false; 24 | config = builtins.readFile "${src}/${file}"; 25 | } else 26 | null; 27 | in { inherit name value; })) 28 | (attrs: removeAttrs attrs [ "_" ]) 29 | ]; 30 | in { 31 | age.secrets.pia-user-pass.file = "${self}/secrets/root.pia-user-pass.age"; 32 | services.openvpn.servers = configs; 33 | } 34 | -------------------------------------------------------------------------------- /hosts/shared/run-game.nix: -------------------------------------------------------------------------------- 1 | { self, lib, pkgs, ... }: 2 | let 3 | run-game = pkgs.patchShellScript "${self}/scripts/run-game.sh" rec { 4 | name = "run-game"; 5 | destination = "/bin/${name}"; 6 | runtimeInputs = [ pkgs.util-linux ]; 7 | }; 8 | in { 9 | environment.systemPackages = [ run-game ]; 10 | 11 | security.sudo.extraRules = [{ 12 | users = [ "jacob" ]; 13 | commands = [{ 14 | command = lib.getExe run-game; 15 | options = [ "NOPASSWD" ]; 16 | }]; 17 | }]; 18 | 19 | programs.steam = { 20 | enable = true; 21 | # Open ports in the firewall for Steam Remote Play 22 | remotePlay.openFirewall = true; 23 | # Open ports in the firewall for Source Dedicated Server 24 | dedicatedServer.openFirewall = true; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /hosts/shared/touchpad-fix.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: { 2 | # workaround for broken libinput gestures and two-finger scrolling. 3 | # 4 | # note that ${lib.getBin pkgs.kmod} does not return a path ending with /bin 5 | # this may need to be a bug report 6 | powerManagement.powerDownCommands = '' 7 | ${pkgs.kmod}/bin/modprobe -r psmouse 8 | ''; 9 | powerManagement.resumeCommands = '' 10 | ${pkgs.kmod}/bin/modprobe psmouse 11 | ''; 12 | } 13 | -------------------------------------------------------------------------------- /lib/colors/default.nix: -------------------------------------------------------------------------------- 1 | { lib }: 2 | let 3 | # Taking R, G, and B arguments in range 0-255, produce an attribute set. 4 | rgb = r: g: b: { inherit r g b; }; 5 | 6 | # Create a monochrome RGB attrs by a percentage of each channel. 7 | grayRGB = percent: let c = builtins.floor (percent * 255); in rgb c c c; 8 | 9 | listRGB = { r, g, b, a ? null }: [ r g b ] ++ lib.optional (a != null) a; 10 | 11 | # Produces a hexadecimal RRGGBBAA color from an attributes. 12 | # Each channel value is expected to be between 0-255. 13 | # Alpha attribute `a` is not required and may be undefined or null. 14 | hexRGB = rgb@{ r, g, b, a ? null }: 15 | lib.concatStrings 16 | (map (c: lib.lpadString "0" 2 (lib.intToHex c)) (listRGB rgb)); 17 | 18 | # Same as `hexRGB` but prefix with `#`. 19 | hexRGB' = rgb: "#${hexRGB rgb}"; 20 | 21 | # Like `hexRGB` but takes alpha as float in a separate argument. 22 | hexRGBA = rgb: a: 23 | let a' = builtins.floor (a * 255); 24 | in hexRGB (rgb // { a = a'; }); 25 | 26 | # Like `hexRGBA` but prefix with `#`. 27 | hexRGBA' = rgb: a: "#${hexRGBA rgb a}"; 28 | 29 | palettes = { gruvbox = import ./palettes/gruvbox.nix { inherit rgb; }; }; 30 | 31 | isRGBAttrs = expr: lib.isAttrs expr && lib.hasExactAttrs [ "r" "g" "b" ] expr; 32 | 33 | # Recurse deeply into attrs and lists, and transform each RGB attrs by `op`. 34 | transformPalette = op: 35 | lib.mapRecursiveCond (expr: !(isRGBAttrs expr)) 36 | (_: expr: if isRGBAttrs expr then op expr else expr); 37 | in { 38 | # FUNCTIONS # 39 | inherit rgb grayRGB listRGB hexRGB hexRGB' hexRGBA hexRGBA'; 40 | # COLORS # 41 | inherit palettes; 42 | formats = { 43 | # Pre-transform palettes by specified `op` functor. 44 | custom = op: transformPalette op palettes; 45 | 46 | listRGB = transformPalette listRGB palettes; 47 | 48 | # Each color attribute is a value according 49 | # to the format functor that produces it. 50 | hexRGB = transformPalette hexRGB palettes; 51 | hexRGB' = transformPalette hexRGB' palettes; 52 | 53 | # For palettes ending with `A`, each color attribute is a function 54 | # to which an alpha float value must be applied. 55 | hexRGBA = transformPalette hexRGBA palettes; 56 | hexRGBA' = transformPalette hexRGBA' palettes; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /lib/default.nix: -------------------------------------------------------------------------------- 1 | lib: lib0: 2 | let 3 | libAttrs = 4 | lib.mapAttrs (_: fn: fn { inherit lib; }) (lib.importDir ./. "default.nix"); 5 | in lib0 // { 6 | birdos = { 7 | lib = libAttrs; 8 | inherit (libAttrs) colors; 9 | 10 | parseUserAtHost = userAtHost: 11 | let 12 | groups = 13 | builtins.match "([a-zA-Z][a-zA-Z0-9_-]+)@([a-zA-Z][a-zA-Z0-9_-]+)" 14 | userAtHost; 15 | in if builtins.length groups != 2 then 16 | null 17 | else { 18 | user = builtins.elemAt groups 0; 19 | host = builtins.elemAt groups 1; 20 | }; 21 | }; 22 | 23 | systems = lib0.systems // { 24 | architectures = lib0.systems.architectures // { 25 | featureSupport = arch: 26 | lib.mapAttrs (_: f: f arch) lib.systems.architectures.predicates; 27 | }; 28 | }; 29 | 30 | maintainers.spikespaz = { 31 | email = "jacob@birkett.dev"; 32 | github = "spikespaz"; 33 | githubId = "MDQ6VXNlcjEyNTAyOTg4"; 34 | name = 12502988; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /misc/eww/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: { 2 | programs.eww.enable = true; 3 | programs.eww.package = pkgs.eww-wayland; 4 | # programs.eww.configDir = ./.; 5 | } 6 | -------------------------------------------------------------------------------- /misc/eww/eww.scss: -------------------------------------------------------------------------------- 1 | $gb-dark0_hard: rgb(29, 32, 33); 2 | $gb-dark0: rgb(40, 40, 40); 3 | $gb-dark0_soft: rgb(50, 48, 47); 4 | $gb-dark1: rgb(60, 56, 54); 5 | $gb-dark2: rgb(80, 73, 69); 6 | $gb-dark3: rgb(102, 92, 84); 7 | $gb-dark4: rgb(124, 111, 100); 8 | $gb-gray: rgb(146, 131, 116); 9 | $gb-light0_hard: rgb(249, 245, 215); 10 | $gb-light0: rgb(253, 244, 193); 11 | $gb-light0_soft: rgb(242, 229, 188); 12 | $gb-light1: rgb(235, 219, 178); 13 | $gb-light2: rgb(213, 196, 161); 14 | $gb-light3: rgb(189, 174, 147); 15 | $gb-light4: rgb(168, 153, 132); 16 | $gb-bright_red: rgb(251, 73, 52); 17 | $gb-bright_green: rgb(184, 187, 38); 18 | $gb-bright_yellow: rgb(250, 189, 47); 19 | $gb-bright_blue: rgb(131, 165, 152); 20 | $gb-bright_purple: rgb(211, 134, 155); 21 | $gb-bright_aqua: rgb(142, 192, 124); 22 | $gb-bright_orange: rgb(254, 128, 25); 23 | $gb-neutral_red: rgb(204, 36, 29); 24 | $gb-neutral_green: rgb(152, 151, 26); 25 | $gb-neutral_yellow: rgb(215, 153, 33); 26 | $gb-neutral_blue: rgb(69, 133, 136); 27 | $gb-neutral_purple: rgb(177, 98, 134); 28 | $gb-neutral_aqua: rgb(104, 157, 106); 29 | $gb-neutral_orange: rgb(214, 93, 14); 30 | $gb-faded_red: rgb(157, 0, 6); 31 | $gb-faded_green: rgb(121, 116, 14); 32 | $gb-faded_yellow: rgb(181, 118, 20); 33 | $gb-faded_blue: rgb(7, 102, 120); 34 | $gb-faded_purple: rgb(143, 63, 113); 35 | $gb-faded_aqua: rgb(66, 123, 88); 36 | $gb-faded_orange: rgb(175, 58, 3); 37 | 38 | $background-alpha: 0.5; 39 | $foreground-alpha: 0.75; 40 | $background-color: rgba(0, 0, 0, $background-alpha); 41 | $text-color: $gb-light0_hard; 42 | $text-font-family: "Ubuntu"; 43 | $text-font-size: 11pt; 44 | $text-font-weight: bold; 45 | $button-hover-background-color: rgba(0, 0, 0, $background-alpha); 46 | // $button-hover-text-color: $gb-dark0_hard; 47 | $button-hover-underline-color: rgba($gb-bright_orange, $foreground-alpha); 48 | $button-hover-underline-weight: 2px; 49 | 50 | .bar { 51 | * { 52 | all: unset; 53 | font-family: $text-font-family; 54 | font-size: $text-font-size; 55 | font-weight: $text-font-weight; 56 | } 57 | 58 | background: $background-color; 59 | 60 | button { 61 | // box-sizing: border-box; 62 | // min-height: 0; 63 | 64 | &:hover { 65 | background: $button-hover-background-color; 66 | 67 | label { 68 | margin-bottom: -$button-hover-underline-weight; 69 | } 70 | 71 | border-bottom: $button-hover-underline-weight $button-hover-underline-color solid; 72 | 73 | // color: $button-hover-text-color; 74 | // box-shadow: 0 0 0 2px $busstton-hover-underline-color inset; 75 | // padding-bottom: -2px; 76 | // outline-offset: -2px; 77 | // border-bottom: 2px $button-hover-underline-color solid; 78 | } 79 | } 80 | 81 | // .workspaces>button.active { 82 | // background-color: red; 83 | // } 84 | 85 | .workspaces>button { 86 | padding: 2; 87 | } 88 | 89 | .datetime { 90 | padding-left: 8px; 91 | padding-right: 8px; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /misc/eww/eww.yuck: -------------------------------------------------------------------------------- 1 | (defwindow bar 2 | :monitor 0 3 | :stacking "overlay" 4 | :exclusive true 5 | :geometry (geometry 6 | :x "0%" 7 | :y "0%" 8 | :width "100%" 9 | :height "26px" 10 | :anchor "top center") 11 | (bar)) 12 | 13 | (defwidget bar [] 14 | (centerbox 15 | :class "bar" 16 | :orientation "h" 17 | (bar-start) 18 | (bar-center) 19 | (bar-end))) 20 | 21 | (defwidget bar-start [] 22 | (box 23 | :class "bar-start" 24 | :orientation "h" 25 | :space-evenly true 26 | :spacing 6 27 | :halign "start" 28 | (workspaces))) 29 | 30 | (defwidget bar-center [] 31 | (box 32 | :class "bar-center" 33 | :orientation "h" 34 | :space-evenly true 35 | :spacing 6 36 | :halign "middle" 37 | (datetime))) 38 | 39 | (defwidget bar-end [] 40 | (box 41 | :class "bar-end" 42 | :orientation "h" 43 | :space-evenly true 44 | :spacing 6 45 | :halign "end" 46 | (battery))) 47 | 48 | (defwidget workspaces [] 49 | (box 50 | :class "workspaces" 51 | :orientation "h" 52 | :halign "middle" 53 | (workspace-button :name "1") 54 | (workspace-button :name "2") 55 | (workspace-button :name "3") 56 | (workspace-button :name "4") 57 | (workspace-button :name "5") 58 | (workspace-button :name "6") 59 | (workspace-button :name "7") 60 | (workspace-button :name "8") 61 | (workspace-button :name "9") 62 | (workspace-button :name "10"))) 63 | 64 | (defwidget workspace-button [name] 65 | (button 66 | :onclick `hyprctl dispatch workspace ${name}` 67 | {name})) 68 | 69 | (defpoll time :interval "10s" `date +'%a, %b %-d, %Y - %-I:%M %p'`) 70 | (defwidget datetime [] 71 | (button 72 | :class "datetime" 73 | :onclick '${EWW_CMD} open --toggle calendar' 74 | {time})) 75 | 76 | (defwindow calendar 77 | :monitor 0 78 | :geometry (geometry 79 | :x "0%" 80 | :y "0%" 81 | :width "300px" 82 | :height "200px" 83 | :anchor "top center") 84 | (box 85 | :class "calendar" 86 | :orientation "v" 87 | (calendar 88 | :show-details true 89 | :show-heading true) 90 | (label :text "America/Phoenix"))) 91 | 92 | ; (defpoll battery) 93 | (defwidget battery [] 94 | (box 95 | :class "battery" 96 | :orientation "h" 97 | :tooltip {EWW_BATTERY} 98 | ; (image :path "./icons/battery") 99 | (label :text `${round(EWW_BATTERY.total_avg, 0)}%`))) 100 | 101 | (defwidget cpu-usage [] 102 | (box 103 | :class "cpu-usage" 104 | :orientation "h" 105 | :haligh "middle" 106 | (graph 107 | ; :class "cpu-usage" 108 | :value 50 109 | :thickness 1.0 110 | ; :geometry (geometry 111 | ; :width 20 112 | ; :height 20) 113 | :time-range "30s"))) 114 | 115 | ; (defwidget user [] 116 | ; (box 117 | ; :class "user" 118 | ; :orientation "h" 119 | ; :halign "middle" 120 | ; (label :text {}))) 121 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-10.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-20.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-30.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-40.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-50.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-60.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-70.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-80.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/eww/icons/battery/battery-90.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /misc/refind-nvme.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -eux 3 | 4 | OS_ROOT=/dev/nvme0n1p3 5 | EFI_TARGET=/dev/sda 6 | EFI_PART=/dev/sda1 7 | 8 | sgdisk -Z $EFI_TARGET 9 | sgdisk -n1:1M:500M -t1:ef00 $EFI_TARGET 10 | 11 | partprobe $EFI_TARGET 12 | sleep 1 13 | 14 | mkfs.vfat -F32 $EFI_PART 15 | 16 | mkdir -p /target 17 | 18 | mount $OS_ROOT /target 19 | 20 | # mount in preparation for chroot 21 | mount $EFI_PART /target/boot/efi 22 | mount --bind /dev /target/dev 23 | mount --bind /dev/pts /target/dev/pts 24 | mount --bind /proc /target/proc 25 | mount --bind /sys /target/sys 26 | 27 | # chroot and reconfigure bootloader + initramfs 28 | chroot /target /bin/bash -x <<- EOF 29 | shopt -s extglob 30 | 31 | apt-add-repository -y ppa:rodsmith/refind 32 | apt update 33 | apt upgrade -y 34 | apt install -y refind 35 | 36 | cd /tmp 37 | 38 | REFIND_VER='0.13.3.1' 39 | 40 | if [ ! -f refind-bin.zip ]; then 41 | wget \ 42 | -O refind-bin.zip \ 43 | "https://cfhcable.dl.sourceforge.net/project/refind/$REFIND_VER/refind-bin-$REFIND_VER.zip" 44 | 7z x ./refind-bin.zip 45 | fi 46 | 47 | if [ ! -f NvmExpressDxe.efi ]; then 48 | wget \ 49 | -O clover.zip \ 50 | 'https://github.com/CloverHackyColor/CloverBootloader/releases/download/5149/CloverV2-5149.zip' 51 | 7z e ./clover.zip CloverV2/EFI/CLOVER/drivers/off/UEFI/Other/NvmExpressDxe.efi 52 | fi 53 | 54 | REFIND_DIR='/boot/efi/EFI/refind' 55 | DRIVERS_DIR="$REFIND_DIR/drivers_x64" 56 | REFIND_FROM="refind-bin-$REFIND_VER/refind" 57 | 58 | mkdir -p $DRIVERS_DIR 59 | 60 | # copy icons over 61 | cp -r $REFIND_FROM/icons $REFIND_DIR 62 | 63 | # copy the boot manager 64 | cp $REFIND_FROM/refind_x64.efi $REFIND_DIR 65 | 66 | # copy the default config and modify 67 | cp $REFIND_FROM/refind.conf-sample $REFIND_DIR 68 | cp $REFIND_FROM/refind.conf-sample $REFIND_DIR/refind.conf 69 | sed -i 's/timeout 20/timeout 2/' $REFIND_DIR/refind.conf 70 | 71 | # copy drivers 72 | cp $REFIND_FROM/drivers_x64/ext4_x64.efi $DRIVERS_DIR 73 | cp NvmExpressDxe.efi $DRIVERS_DIR 74 | 75 | # add the entry to nvram 76 | efibootmgr -c -l '\\EFI\\refind\\refind_x64.efi' -L rEFInd 77 | EOF 78 | 79 | # clean up the chroot mounts 80 | umount /target/sys 81 | umount /target/proc 82 | umount /target/dev/pts 83 | umount /target/dev 84 | umount /target/boot/efi 85 | umount /target 86 | -------------------------------------------------------------------------------- /misc/zorin/grub-hdd-to-nvme.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # shellcheck disable=SC2086 3 | set -euxo pipefail 4 | 5 | 6 | # Calculate preferred swap partition size for hibernation 7 | TOTAL_MEM=$(awk '{if ($1 == "MemTotal:") print $2}' /proc/meminfo) 8 | EXTRA_SWAP=$((2 * 1024 * 1024)) 9 | TOTAL_SWAP="$((TOTAL_MEM + EXTRA_SWAP))K" # KiB 10 | 11 | SOURCE_DEV='/dev/sda' 12 | TARGET_DEV='/dev/nvme0n1' 13 | EFI_BLOCK="${SOURCE_DEV}1" 14 | SOURCE_ROOT="${SOURCE_DEV}2" 15 | 16 | # clear root drive 17 | sgdisk -Z $TARGET_DEV 18 | # create swap 19 | sgdisk -n1:1M:+$TOTAL_SWAP -t1:8200 $TARGET_DEV 20 | # create root 21 | sgdisk -n2:0:0 -t2:8304 $TARGET_DEV 22 | 23 | mapfile -t new_blocks < <(lsblk -no PATH $TARGET_DEV) 24 | new_swap_blk="${new_blocks[1]}" 25 | new_root_blk="${new_blocks[2]}" 26 | 27 | # notify kernel 28 | partprobe $TARGET_DEV 29 | sleep 1 30 | 31 | # make new swap partition 32 | mkswap -L swap $new_swap_blk 33 | 34 | # copy over the old partition 35 | dd if=$SOURCE_ROOT of=$new_root_blk bs=4M status=progress 36 | 37 | # randomize the new root's guid 38 | sgdisk -G $TARGET_DEV 39 | 40 | # make new mount points 41 | mkdir /mnt/boot 42 | mkdir /target 43 | 44 | # mount the og boot and new root 45 | mount $EFI_BLOCK /mnt/boot 46 | mount $new_root_blk /target 47 | 48 | # recurse copy the boot folder to efi 49 | rm -d /target/boot/efi 50 | cp -fLr /target/boot/* /mnt/boot 51 | # remove old boot files 52 | rm -rf /target/boot/* 53 | 54 | # unmount old efi 55 | umount /mnt/boot 56 | 57 | # mount in preparation for chroot 58 | mount $EFI_BLOCK /target/boot 59 | mount --bind /dev /target/dev 60 | mount --bind /dev/pts /target/dev/pts 61 | mount --bind /proc /target/proc 62 | mount --bind /sys /target/sys 63 | 64 | # add modules for nvme in initramfs 65 | cat <<- EOF >> /target/etc/initramfs-tools/modules 66 | nvme 67 | vmd 68 | EOF 69 | 70 | # find the uuid of each fstab entry 71 | root_uuid=$(lsblk -no UUID $new_root_blk) 72 | efi_uuid=$(lsblk -no UUID $EFI_BLOCK) 73 | swap_uuid=$(lsblk -no UUID $new_swap_blk) 74 | 75 | # write the new fstab 76 | cat <<- EOF > /target/etc/fstab 77 | UUID=$root_uuid / ext4 errors=remount-ro 0 1 78 | UUID=$efi_uuid /boot vfat umask=0077 0 1 79 | UUID=$swap_uuid none swap sw 0 0 80 | EOF 81 | 82 | # enable hibernation to swap 83 | sed -i "s;\(GRUB_CMDLINE_LINUX_DEFAULT\)=\"\(.*\)\";\1=\"\2 resume=UUID=$swap_uuid\";" \ 84 | /target/etc/default/grub 85 | 86 | # copy the zorin theme to esp so that grub can find it before nvme load 87 | cp -r /usr/share/grub/themes/zorin /target/boot/EFI/ubuntu 88 | sed -i 's|\(GRUB_THEME\)=.*|\1=/boot/EFI/ubuntu/zorin/theme.txt|' \ 89 | /target/etc/default/grub 90 | 91 | # maybe needed to reduce the size of initramfs image 92 | #echo 'MODULES=dep' > /target/etc/initramfs-tools/conf.d/modules 93 | 94 | # clear the original root partition 95 | # we don't want it picked up by os-prober 96 | sgdisk -d2 $SOURCE_DEV 97 | 98 | # chroot and reconfigure bootloader + initramfs 99 | chroot /target /bin/bash -x <<- EOF 100 | set -ev 101 | # delete the old initramfs images 102 | update-initramfs -d -k all 103 | # generate new ones from scratch 104 | update-initramfs -c -k all 105 | # re-write the grub config 106 | grub-mkconfig -o /boot/EFI/ubuntu/grub.cfg 107 | # install grub again 108 | grub-install \ 109 | --efi-directory /boot \ 110 | --bootloader-id ubuntu 111 | EOF 112 | 113 | # clean up the chroot mounts 114 | umount /target/sys 115 | umount /target/proc 116 | umount /target/dev/pts 117 | umount /target/dev 118 | umount /target/boot 119 | umount /target 120 | 121 | rm -d /mnt/boot 122 | rm -d /target 123 | -------------------------------------------------------------------------------- /misc/zorin/logind-hibernate.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # enable logind hibernation 3 | cat <<- EOF > /etc/polkit-1/localauthority/50-local.d/com.ubuntu.enable-hibernate.pkla 4 | [Enable hibernate] 5 | Identity=unix-user:* 6 | Action=org.freedesktop.login1.hibernate;org.freedesktop.login1.handle-hibernate-key;org.freedesktop.login1;org.freedesktop.login1.hibernate-multiple-sessions 7 | ResultActive=yes 8 | EOF 9 | 10 | # 11 | # 12 | -------------------------------------------------------------------------------- /modules/amdctl/apply-pstate-voltages.sh: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | set -eu 3 | 4 | dry_run_args=() 5 | mode= 6 | values=() 7 | 8 | while [[ $# -ne 0 ]]; do 9 | case $1 in 10 | --dry) 11 | dry_run_args+=(-t) 12 | shift 13 | ;; 14 | inc) 15 | mode='inc' 16 | shift 17 | ;; 18 | dec) 19 | mode='dec' 20 | shift 21 | ;; 22 | set) 23 | mode='set' 24 | shift 25 | ;; 26 | *) 27 | values+=("$1") 28 | shift 29 | esac 30 | done 31 | 32 | if [[ -z $mode ]]; then 33 | echo 'Missing positional parameter MODE, must be one of: inc, dec, or set' 34 | exit 1 35 | fi 36 | 37 | get_vid() { 38 | local output 39 | output="$(amdctl "-c$1" "-p$2" "-u$3")" 40 | if [[ "$output" =~ ^.+vid\ ([0-9]+).+$ ]]; then 41 | printf '%s' "${BASH_REMATCH[1]}" 42 | else 43 | return 1 44 | fi 45 | } 46 | 47 | # get the current pstate info 48 | output=$(amdctl -g) 49 | 50 | core= 51 | pstate= 52 | lowest_pstate= 53 | voltages=() 54 | 55 | # read lines of output 56 | while read -r line; do 57 | # new pstate table for core, with lowest pstate 58 | if [[ "$line" =~ ^Core\ ([0-9]+).+Lowest\ ([0-9]+).+$ ]]; then 59 | core="${BASH_REMATCH[1]}" 60 | lowest_pstate="${BASH_REMATCH[2]}" 61 | # skip a line its empty 62 | read -r _ || break 63 | while read -r line; do 64 | # looks like a table row 65 | if [[ "$line" =~ ^([0-9]+).+\ +([0-9]+)mV.+$ ]]; then 66 | pstate="${BASH_REMATCH[1]}" 67 | voltage="${BASH_REMATCH[2]}" 68 | voltages+=("$core $pstate $voltage") 69 | # we are at the end of the table 70 | [[ $pstate -eq $lowest_pstate ]] && break 71 | fi 72 | done 73 | fi 74 | # empty lines or those not matching are skipped 75 | done <<< "$output" 76 | 77 | failed=() 78 | commands=() 79 | 80 | for tuple in "${voltages[@]}"; do 81 | read -r -a tuple <<< "$tuple" 82 | core="${tuple[0]}" 83 | pstate="${tuple[1]}" 84 | voltage="${tuple[2]}" 85 | 86 | echo 87 | echo "Core $core, Pstate $pstate, CpuVolt ${voltage}mV" 88 | 89 | value="${values[$pstate]}" 90 | case "$mode" in 91 | inc) 92 | voltage=$((voltage + value)) 93 | ;; 94 | dec) 95 | voltage=$((voltage - value)) 96 | ;; 97 | set) 98 | voltage=$value 99 | ;; 100 | esac 101 | 102 | if vid="$(get_vid "$core" "$pstate" "$voltage")"; then 103 | commands+=("amdctl ${dry_run_args[@]} -c$core -p$pstate -v$vid") 104 | echo "CpuVolt = ${voltage}mV" 105 | echo "CpuVid = ${vid}" 106 | else 107 | failed+=("$core $pstate $voltage") 108 | echo "FAILURE: could not find CpuVid for ${voltage}mv" 109 | fi 110 | done 111 | 112 | # shellcheck disable=SC2015 113 | [[ ${#failed[@]} -ne 0 ]] && exit 33 || true 114 | 115 | for command in "${commands[@]}"; do 116 | $command 117 | done 118 | -------------------------------------------------------------------------------- /modules/amdctl/default.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, config, ... }: 2 | let 3 | cfg = config.services.undervolt.amdctl; 4 | inherit (lib) types; 5 | in { 6 | options = { 7 | services.undervolt.amdctl = { 8 | enable = lib.mkEnableOption '' 9 | Whether to enable the systemd unit for starting `amdctl` 10 | on requisite events to maintain a constant undervolt during 11 | different p-states during normal machine operation. 12 | 13 | The service will fail with code 33 if you have provided invalid 14 | offset values (recommend multiples of 100). 15 | ''; 16 | 17 | package = lib.mkOption { 18 | type = types.package; 19 | default = pkgs.amdctl; 20 | description = '' 21 | The package to use for the `amdctl` binary. 22 | ''; 23 | }; 24 | 25 | mode = lib.mkOption { 26 | type = types.enum [ "inc" "dec" "set" ]; 27 | default = "dec"; 28 | description = '' 29 | By default, {option}`pstateValues` are subtracted from whatever is 30 | current for each core when the service is executed. 31 | This is `dec` mode. 32 | 33 | Alternatively, use `set` to apply the {option}`pstateValues` 34 | to each core's pstates directly, not subtracting or adding. 35 | 36 | While the module is technically for undervolting, 37 | if you change {option}`mode` to `inc` you can add 38 | each of {option}`pstateValues` instead of subtracting 39 | (overvolt instead of undervolt). 40 | ''; 41 | }; 42 | 43 | pstateVoltages = lib.mkOption { 44 | type = types.nullOr (types.listOf types.ints.unsigned); 45 | default = null; 46 | description = '' 47 | > **WARNING:** 48 | > For now this module assumes all cores 49 | > have the same pstates and default voltages. 50 | > The script does set each core and pstate voltage independently, 51 | > so module options can easily be changed in the future 52 | > if necessary (for BIG.little CPUs for example). 53 | 54 | A list of offset values in mV to apply to the pstate 55 | at the corresponding index. 56 | 57 | For example, `[150 100 100]` would apply to a system with 58 | three pstates: 59 | 60 | ``` 61 | p0 = 1218mv - 150mV = 1068mV 62 | p1 = 950mV - 100mV = 850mV 63 | p2 = 912mV - 100mV = 812mV 64 | ``` 65 | ''; 66 | }; 67 | }; 68 | }; 69 | 70 | config = lib.mkIf cfg.enable { 71 | # 72 | environment.systemPackages = [ cfg.package ]; 73 | 74 | boot.kernelModules = [ "msr" ]; 75 | boot.kernelParams = [ "msr.allow_writes=on" ]; 76 | 77 | systemd.services.undervolt-amdctl = 78 | let targets = [ "multi-user.target" "post-resume.target" ]; 79 | in { 80 | serviceConfig.Type = "oneshot"; 81 | path = [ cfg.package ]; 82 | description = "control undervolt with amdctl"; 83 | documentation = [ "https://github.com/kevinlekiller/amdctl" ]; 84 | after = targets; 85 | wantedBy = targets; 86 | script = lib.escapeShellArgs 87 | ([ ./apply-pstate-voltages.sh cfg.mode ] ++ cfg.pstateVoltages); 88 | }; 89 | 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /modules/qmk-devices.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, config, ... }: 2 | let 3 | inherit (lib) types; 4 | cfg = config.hardware.keyboard.qmk; 5 | hardwareIdentifier = types.strMatching "[A-Fa-f0-9]{4}"; 6 | in { 7 | options = { 8 | hardware.keyboard = { 9 | qmk.extraDevices = lib.mkOption { 10 | type = types.listOf (types.submodule ({ config, ... }: { 11 | options = { 12 | name = lib.mkOption { 13 | type = types.nullOr types.singleLineStr; 14 | description = 15 | "The friendly name for this device (or just vendor)"; 16 | default = null; 17 | }; 18 | vendorId = lib.mkOption { 19 | type = hardwareIdentifier; 20 | description = "The vendor ID as shown from `lsusb`."; 21 | }; 22 | productId = lib.mkOption { 23 | type = types.nullOr hardwareIdentifier; 24 | default = null; 25 | description = "The vendor ID as shown from `lsusb`."; 26 | }; 27 | udevRules = lib.mkOption { 28 | type = types.nonEmptyStr; 29 | internal = true; 30 | readOnly = true; 31 | }; 32 | }; 33 | config = { 34 | udevRules = '' 35 | ${lib.optionalString (config.name != null) "# ${config.name}"} 36 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="${config.vendorId}", ${ 37 | lib.optionalString (config.productId != null) 38 | ''ATTR{idProduct}=="${config.productId}", '' 39 | }MODE="0666" 40 | KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="${config.vendorId}", ${ 41 | lib.optionalString (config.productId != null) 42 | ''ATTRS{idProduct}=="${config.productId}", '' 43 | }MODE="0660", GROUP="users", TAG+="uaccess", TAG+="udev-acl" 44 | ''; 45 | }; 46 | })); 47 | }; 48 | }; 49 | }; 50 | config = lib.mkIf (cfg != [ ]) { 51 | services.udev.packages = [ 52 | (pkgs.writeTextDir "/lib/udev/rules.d/51-qmk-extra.rules" 53 | (lib.concatLines (lib.catAttrs "udevRules" cfg.extraDevices))) 54 | ]; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /overlays/default.nix: -------------------------------------------------------------------------------- 1 | lib: packageOverlays: 2 | lib.updates [ 3 | # Include all overlays from the current directory 4 | # (excluding `default.nix` as it is not an overlay). 5 | (lib.importDir' ./. "default.nix") 6 | # Also include each package overlay, as it is named. 7 | packageOverlays 8 | { 9 | # The `default` overlay includes all the packages 10 | # (and package sets) exported by this flake. 11 | # 12 | # The overlay `allowUnfree` is not included by default. 13 | # This is because the user should be explicitly aware 14 | # that they are using the "hack". 15 | default = lib.composeManyExtensions (lib.attrValues packageOverlays); 16 | 17 | # This overlay is included as a hack to make the packages (last argument) 18 | # easier to work with. Proper handling of unfree packages is really confusing, 19 | # so this is here to make sure there's an easy way to get stuff to work. 20 | allowUnfree = pkgs: pkgs0: 21 | lib.bird.mkUnfreeOverlay pkgs0 [ [ "ttf-ms-win11" ] ]; 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /overlays/hacks/nixpkgs-config-exceptions.nix: -------------------------------------------------------------------------------- 1 | # This overlay attempts to replace packages which take a very long time to build with 2 | # `nixpkgs` using custom platform settings. 3 | pkgs: pkgs0: 4 | let 5 | # Attempt to construct a `pkgs` instance which matches the current fix-point `pkgs`, 6 | # without extra customizations to `stdenv` (or any overlays). 7 | # The arguments used for the new `localSystem` and `crossSystem` are not exactly correct, 8 | # the code below is just an approximation achieved by reading `pkgs/stdenv/cross/default.nix`. 9 | # It would be non-trivial to preserve the semantic intent of the original 10 | # `localSystem` and `crossSystem` which produced the original `pkgs` point. 11 | # I could surgically construct a new set of arguments for the new Nixpkgs import, 12 | # but I would rather not. 13 | unoptimizedPkgs = import "${pkgs}" { 14 | localSystem.system = pkgs.stdenvNoCC.buildPlatform.system; 15 | crossSystem.system = pkgs.stdenvNoCC.targetPlatform.system; 16 | }; 17 | in { 18 | # This will interfere with other overlays. A more surgical approach is necessary if desire is otherwise. 19 | 20 | qt6Packages = pkgs0.qt6Packages.overrideScope 21 | (_: _: { qtwebengine = unoptimizedPkgs.qt6Packages.qtwebengine; }); 22 | 23 | kdePackages = pkgs0.kdePackages.overrideScope 24 | (_: _: { qtwebengine = unoptimizedPkgs.kdePackages.qtwebengine; }); 25 | } 26 | -------------------------------------------------------------------------------- /overlays/oraclejdk.nix: -------------------------------------------------------------------------------- 1 | pkgs: pkgs0: { 2 | # Oracle, fuck you. 🖕 3 | # 4 | # 5 | # 6 | # 7 | # This override calls `jdk-linux-base.nix` with product information 8 | # matching a tarball that we can get from the link above. 9 | # 10 | # In order to hide the "we can't download that for you" message 11 | # shown by `pkgs.requireFile` in the nixpkgs source, 12 | # we hijack the `requireFile` function passed to `package` below, 13 | # and if the name matches the product information for this 14 | # shady tarball, substitute it with the automatic download. 15 | # 16 | # Note that this does not take into account anything except the basic 17 | # default package options. If you need the JCE for example, you're on your own. 18 | # 19 | # Read up on the nixpkgs source to understand this more: 20 | # 21 | oraclejdk = let 22 | product = { 23 | productVersion = "8"; 24 | patchVersion = "361"; 25 | # for 26 | sha256.x86_64-linux = 27 | "sha256-JYWpJLuNLDFdj+RL+lNPYV94knlliWPTD/4Un9dB2W4="; 28 | # for 29 | # sha256.x86_64-linux = "sha256-YeP0CZqZp3pweFOAizps+ofSuCsZt8dtzGxdPu37O50="; 30 | jceName = null; 31 | sha256JCE = null; 32 | }; 33 | version = "${product.productVersion}u${product.patchVersion}"; 34 | tarballName = "jdk-${version}-${platformName}.tar.gz"; 35 | src = pkgs.fetchzip { 36 | url = 37 | "https://cfdownload.adobe.com/pub/adobe/coldfusion/java/java${product.productVersion}/java${version}/jdk/${tarballName}"; 38 | # url = "https://nadwey.eu.org/java/${product.productVersion}/jdk-${version}/${tarballName}"; 39 | sha256 = product.sha256.${pkgs.system}; 40 | }; 41 | package = import 42 | "${pkgs.path}/pkgs/development/compilers/oraclejdk/jdk-linux-base.nix" 43 | product; 44 | platformName = builtins.getAttr pkgs.system { 45 | i686-linux = "linux-i586"; 46 | x86_64-linux = "linux-x64"; 47 | armv7l-linux = "linux-arm32-vfp-hflt"; 48 | aarch64-linux = "linux-aarch64"; 49 | }; 50 | in pkgs.callPackage package { 51 | installjdk = true; 52 | pluginSupport = false; 53 | requireFile = args@{ name, ... }: 54 | if name == tarballName then src else pkgs.requireFile args; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /overlays/patches.nix: -------------------------------------------------------------------------------- 1 | pkgs: pkgs0: 2 | let inherit (pkgs) lib; 3 | in { 4 | # keepassxc = pkgs0.keepassxc.overrideAttrs (self: super: { 5 | # patches = super.patches or [ ] ++ [ 6 | # (pkgs.fetchpatch { 7 | # url = 8 | # "https://github.com/keepassxreboot/keepassxc/commit/f93adaa854b859dc0bda4ad3422f6f98b269f744.diff"; 9 | # hash = "sha256-D5HRUOonLZOmjmLevSzh+OaQ8pR2E4yfgnEJwFWMP0I="; 10 | # }) 11 | # ]; 12 | # }); 13 | 14 | # TODO pull request 15 | shotcut = pkgs0.shotcut.overrideAttrs (self: super: { 16 | buildInputs = super.buildInputs or [ ] ++ [ pkgs.qt6.qtwayland ]; 17 | }); 18 | 19 | vscode-marketplace = pkgs0.vscode-marketplace // { 20 | slint = pkgs0.vscode-marketplace.slint // { 21 | slint = pkgs0.vscode-marketplace.slint.slint.overrideAttrs (self: super: { 22 | postInstall = super.postInstall or "" + '' 23 | extBin=$out/share/vscode/extensions/slint.slint/bin/ 24 | rm $out/share/vscode/extensions/slint.slint/bin/slint-lsp-* 25 | cp ${lib.getExe pkgs.slint-lsp} \ 26 | $extBin/slint-lsp-${pkgs.hostPlatform.config} 27 | ''; 28 | }); 29 | }; 30 | }; 31 | 32 | swaylock-effects = pkgs0.swaylock-effects.overrideAttrs (self: super: { 33 | patches = super.patches or [ ] ++ [ 34 | # Pull request #49 for proper fprintd support. 35 | (pkgs.fetchpatch { 36 | url = 37 | "https://patch-diff.githubusercontent.com/raw/jirutka/swaylock-effects/pull/49.diff"; 38 | hash = "sha256-hbPRFiKFxC2+TtadDSdlrgZlP/9/VHwasGZiCa7sT3A="; 39 | }) 40 | ]; 41 | mesonFlags = super.mesonFlags ++ [ "-Dfingerprint=enabled" ]; 42 | # The `build.meson` does not use `pkg-config` for DBus interfaces, 43 | # therefor `PKG_CONFIG_DBUS_1_INTERFACES_DIR` does not apply. 44 | # 45 | postPatch = let 46 | dbusInterfacesDir = (pkgs.symlinkJoin { 47 | name = "${self.pname}-${self.version}_dbus-interfaces-dir"; 48 | paths = self.buildInputs; 49 | pathsToLink = [ "share/dbus-1/interfaces" ]; 50 | }) + "/share/dbus-1/interfaces"; 51 | in super.postPatch or "" + '' 52 | sed -i 's@/usr/share/dbus-1/interfaces@${dbusInterfacesDir}@g' \ 53 | fingerprint/meson.build 54 | ''; 55 | buildInputs = super.buildInputs ++ (with pkgs; [ dbus fprintd ]); 56 | }); 57 | } 58 | -------------------------------------------------------------------------------- /overlays/updates.nix: -------------------------------------------------------------------------------- 1 | pkgs: pkgs0: 2 | let inherit (pkgs) lib; 3 | in { 4 | materia-kde-theme = pkgs0.materia-kde-theme.overrideAttrs (self: _: { 5 | version = "20220823"; 6 | src = pkgs.fetchFromGitHub { 7 | owner = "PapirusDevelopmentTeam"; 8 | repo = "materia-kde"; 9 | rev = self.version; 10 | hash = "sha256-/O+/L6C9WjxhfWZ8RzIeimNU+8sjKvbDvQwNlvVOjU4="; 11 | }; 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/amdctl.nix: -------------------------------------------------------------------------------- 1 | { stdenv, fetchFromGitHub, gnumake }: 2 | stdenv.mkDerivation (self: { 3 | pname = "amdctl"; 4 | version = "0.11"; 5 | nativeBuildInputs = [ gnumake ]; 6 | src = fetchFromGitHub { 7 | owner = "kevinlekiller"; 8 | repo = "amdctl"; 9 | rev = "v${self.version}"; 10 | sha256 = "sha256-2wBk/9aAD7ARMGbcVxk+CzEvUf8U4RS4ZwTCj8cHNNo="; 11 | }; 12 | installPhase = '' 13 | runHook preInstall 14 | make 15 | install -Dm555 ./amdctl $out/bin/amdctl 16 | runHook postInstall 17 | ''; 18 | }) 19 | -------------------------------------------------------------------------------- /packages/default.nix: -------------------------------------------------------------------------------- 1 | { lib, system, nixpkgs }: 2 | let 3 | packageOverlays = builtins.attrValues (import ./overlays.nix lib); 4 | pkgs = import nixpkgs { 5 | localSystem = system; 6 | overlays = packageOverlays; 7 | }; 8 | in lib.updates [ 9 | # INDIVIDUAL PACKAGES # 10 | 11 | (with pkgs; { 12 | inherit amdctl ja-netfilter prtsc ttf-ms-win11 fork-awesome idlehack 13 | proton-ge-custom nerdfonts-symbols; 14 | }) 15 | 16 | { 17 | inherit (pkgs.python3Packages) platformio-python; 18 | } 19 | 20 | # PACKAGE SETS # 21 | 22 | (with pkgs.zsh-plugins; { 23 | zsh-autosuggestions = zsh-autosuggestions; 24 | zsh-autocomplete = zsh-autocomplete; 25 | zsh-edit = zsh-edit; 26 | zsh-autopair = zsh-autopair; 27 | zsh-auto-notify = zsh-auto-notify; 28 | zsh-window-title = zsh-window-title; 29 | zsh-fast-syntax-highlighting = zsh-fast-syntax-highlighting; 30 | }) 31 | ] 32 | -------------------------------------------------------------------------------- /packages/firefox-extensions.nix: -------------------------------------------------------------------------------- 1 | { lib, buildFirefoxXpiAddon }: { 2 | # Clicks the stupid little green loot box for me. 3 | twitch-auto-clicker = let fileId = "3944212"; 4 | in buildFirefoxXpiAddon rec { 5 | pname = "twitchautoclicker"; 6 | version = "0.0.12"; 7 | addonId = "{1af5f0df-ce7b-4b5f-a0e1-b66675ae81f9}"; 8 | url = 9 | "https://addons.mozilla.org/firefox/downloads/file/${fileId}/${pname}-${version}.xpi"; 10 | hash = "sha256-QYvRfWeINibQ6sJQsM/Qj7FjOI5/cVqYzVcg1umNdJc="; 11 | meta = with lib; { 12 | description = 13 | "Auto clicks the Channel Points bonus chest for you, so you can watch streams in peace."; 14 | license = licenses.mit; # all rights reserved 15 | mozPermissions = [ ]; 16 | platforms = platforms.all; 17 | }; 18 | }; 19 | 20 | # Get rid of Twitch's pre-roll ads (mostly). Let me browse in peace. 21 | ttv-lol-pro = buildFirefoxXpiAddon rec { 22 | pname = "ttv_lol_pro"; 23 | version = "2.4.0"; 24 | addonId = "{76ef94a4-e3d0-4c6f-961a-d38a429a332b}"; 25 | url = 26 | "https://github.com/younesaassila/ttv-lol-pro/releases/download/v${version}/v${version}-firefox.zip"; 27 | hash = "sha256-eQDTFwmB4VJRtoECMfWwLRkWzwiefg5FWL+az7sTOLY="; 28 | meta = with lib; { 29 | description = "TTV LOL PRO removes most livestream ads from Twitch."; 30 | license = licenses.gpl3; 31 | mozPermissions = [ 32 | "proxy" 33 | "storage" 34 | "webRequest" 35 | "webRequestBlocking" 36 | "https://*.ttvnw.net/*" 37 | "https://*.twitch.tv/*" 38 | "https://perfprod.com/ttvlolpro/telemetry" 39 | ]; 40 | }; 41 | }; 42 | 43 | # This extension is amazing, check it out if you use Twitch. 44 | frankerfacez = let fileId = "4464564"; 45 | in buildFirefoxXpiAddon rec { 46 | pname = "frankerfacez"; 47 | version = "4.77.3.0"; 48 | addonId = "frankerfacez@frankerfacez.com"; 49 | url = 50 | "https://addons.mozilla.org/firefox/downloads/file/${fileId}/${pname}-${version}.xpi"; 51 | hash = "sha256-CEvsSSHlXgGQvyQhEt7Gs3ke7i/6UNDcLIdXNISpVLM="; 52 | meta = with lib; { 53 | description = 54 | "The Twitch Enhancement Suite - Get custom emotes and tons of new features you'll never want to go without."; 55 | license = licenses.asl20; 56 | mozPermissions = [ 57 | "storage" 58 | "webRequest" 59 | "webRequestBlocking" 60 | "*://*.twitch.tv/*" 61 | "*://*.frankerfacez.com/*" 62 | ]; 63 | }; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /packages/fork-awesome.nix: -------------------------------------------------------------------------------- 1 | { stdenvNoCC, fetchzip, fontFormats ? [ "ttf" "woff" "woff2" ] }: 2 | stdenvNoCC.mkDerivation (self: { 3 | pname = "fork-awesome"; 4 | version = "1.2.0"; 5 | 6 | preferLocalBuild = true; 7 | 8 | src = fetchzip { 9 | url = 10 | "https://github.com/ForkAwesome/Fork-Awesome/archive/${self.version}.zip"; 11 | sha256 = "sha256-zG6/0dWjU7/y/oDZuSEv+54Mchng64LVyV8bluskYzc="; 12 | }; 13 | 14 | inherit fontFormats; 15 | 16 | installPhase = '' 17 | runHook preInstall 18 | 19 | for format in ''${fontFormats[@]}; do 20 | mkdir -p $out/share/fonts/$format 21 | mv ./fonts/*.$format $out/share/fonts/$format/ 22 | done 23 | 24 | runHook postInstall 25 | ''; 26 | }) 27 | -------------------------------------------------------------------------------- /packages/idlehack.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv, fetchFromGitHub, systemdSupport ? stdenv.isLinux, pkg-config 2 | , bash, dbus, systemd, xorg, ... }: 3 | stdenv.mkDerivation (self: { 4 | pname = "idlehack"; 5 | version = "unstable-2021-12-05"; 6 | 7 | src = fetchFromGitHub { 8 | owner = "loops"; 9 | repo = self.pname; 10 | rev = "fd73c76c2d289f9eb9ad9b0695fa9e9f151be22f"; 11 | sha256 = "sha256-vURFnGid52F1Jy5S9O3LRskzzxeyMzlhbwdEYQrUvWc="; 12 | }; 13 | 14 | strictDeps = true; 15 | nativeBuildInputs = [ pkg-config ]; 16 | buildInputs = [ bash dbus xorg.libX11 ] 17 | ++ lib.optionals systemdSupport [ systemd ]; 18 | 19 | installPhase = '' 20 | runHook preInstall 21 | 22 | install -Dm755 ./idlehack $out/bin/idlehack 23 | install -Dm755 ./swayidle-inhibit $out/bin/swayidle-inhibit 24 | sed -i 's;#!/bin/bash;#!bin/sh;' $out/bin/swayidle-inhibit 25 | 26 | runHook postInstall 27 | ''; 28 | 29 | meta = { 30 | description = 31 | "Monitor dbus and inhibit swayidle when Firefox or Chromium request it"; 32 | longDescription = '' 33 | Listen for Firefox/Chromium dbus messages that request screensaver inhibit, 34 | typically because the user is watching video. Sway doesn't currently listen 35 | for such messages, so here we create a daemon that listens for these messages 36 | and then invokes "/bin/swayidle-inhibit" which is responsible for temporarily 37 | disabling the screen blanking. 38 | ''; 39 | inherit (self.src.meta) homepage; 40 | license = lib.licenses.isc; 41 | platforms = lib.platforms.linux; 42 | maintainers = with lib.maintainers; [ spikespaz ]; 43 | mainProgram = "idlehack"; 44 | }; 45 | }) 46 | -------------------------------------------------------------------------------- /packages/ja-netfilter/base.nix: -------------------------------------------------------------------------------- 1 | # use the source luke 2 | # 3 | # 4 | { pname, version, src, depsHash, targetJar, renameJar, }: 5 | { lib, stdenv, callPackage, maven, oraclejdk, buildMaven, }: 6 | let 7 | inherit pname version src; 8 | 9 | mavenDeps = stdenv.mkDerivation { 10 | name = "${pname}-${version}-deps"; 11 | inherit src; 12 | 13 | nativeBuildInputs = [ oraclejdk maven ]; 14 | buildPhase = '' 15 | mvn package \ 16 | -Dmaven.test.skip=true \ 17 | -Dmaven.repo.local=$out \ 18 | -Dmaven.wagon.rto=5000 19 | ''; 20 | 21 | # keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside 22 | installPhase = '' 23 | find $out -type f \ 24 | -name \*.lastUpdated -or \ 25 | -name resolver-status.properties -or \ 26 | -name _remote.repositories \ 27 | -delete 28 | ''; 29 | 30 | outputHashAlgo = "sha256"; 31 | outputHashMode = "recursive"; 32 | outputHash = depsHash; 33 | 34 | doCheck = false; 35 | }; 36 | in stdenv.mkDerivation { 37 | inherit pname version src; 38 | 39 | buildInputs = [ oraclejdk maven ]; 40 | buildPhase = '' 41 | runHook preBuild 42 | 43 | mvn package --offline \ 44 | -Dmaven.test.skip=true \ 45 | -Dmaven.repo.local=${mavenDeps.outPath} 46 | 47 | runHook postBuild 48 | ''; 49 | 50 | installPhase = '' 51 | runHook preInstall 52 | install -Dm644 target/${targetJar} $out/${renameJar} 53 | runHook postInstall 54 | ''; 55 | } 56 | -------------------------------------------------------------------------------- /packages/ja-netfilter/default.nix: -------------------------------------------------------------------------------- 1 | { lib, writeTextDir, callPackage, symlinkJoin, programName ? null 2 | , enabledPlugins ? null, pluginConfigs ? null, }: 3 | let 4 | packages = callPackage ./packages.nix { }; 5 | ja-netfilter = callPackage packages.ja-netfilter { }; 6 | callPlugin = name: callPackage packages."plugin-${name}" { }; 7 | pluginPackages = 8 | lib.optionals (enabledPlugins != null) (map callPlugin enabledPlugins); 9 | configFiles = lib.optionals (pluginConfigs != null) (lib.mapAttrsToList 10 | (name: value: writeTextDir "share/ja-netfilter/config/${name}.conf" value) 11 | pluginConfigs); 12 | in symlinkJoin { 13 | name = if programName == null then 14 | "ja-netfilter" 15 | else 16 | "ja-netfilter-${programName}"; 17 | paths = [ ja-netfilter ] ++ pluginPackages ++ configFiles; 18 | postBuild = lib.optionalString (programName != null) '' 19 | mv $out/share/ja-netfilter/plugins $out/share/ja-netfilter/plugins-${programName} 20 | mv $out/share/ja-netfilter/config $out/share/ja-netfilter/config-${programName} 21 | ''; 22 | } 23 | -------------------------------------------------------------------------------- /packages/ja-netfilter/packages.nix: -------------------------------------------------------------------------------- 1 | { fetchgit, }: 2 | let 3 | repoOwner = "ja-netfilter"; 4 | baseName = "ja-netfilter"; 5 | 6 | packageBase = import ./base.nix; 7 | pluginBase = { name, version, srcHash, depsHash, }: 8 | packageBase { 9 | pname = "${baseName}-plugin-${name}"; 10 | src = fetchgit { 11 | url = "https://gitee.com/${repoOwner}/plugin-${name}.git"; 12 | rev = version; 13 | sha256 = srcHash; 14 | }; 15 | # maven outputs the jar name with an extra `v` in the version segment 16 | targetJar = "${name}-v${version}-jar-with-dependencies.jar"; 17 | renameJar = "share/${baseName}/plugins/${name}.jar"; 18 | inherit version depsHash; 19 | }; 20 | in { 21 | ja-netfilter = packageBase rec { 22 | pname = baseName; 23 | version = "2022.2.0"; 24 | src = fetchgit { 25 | url = "https://gitee.com/${repoOwner}/ja-netfilter.git"; 26 | rev = version; 27 | sha256 = "sha256-jlRJ2r9EnbaqG7tGhJduFCchORdraZL3aTBa1btgMIU="; 28 | }; 29 | depsHash = "sha256-B8kZKC1FilK/wWNzlrQgDVj+T0EhScK2o2lAtFK8FqY="; 30 | targetJar = "ja-netfilter-jar-with-dependencies.jar"; 31 | renameJar = "share/${baseName}/ja-netfilter.jar"; 32 | }; 33 | plugin-dns = pluginBase { 34 | name = "dns"; 35 | version = "v1.1.0"; 36 | srcHash = "sha256-JSBGjQY7KmO7pcrATY5Ql9eg+hQUHqy9869uINLz+Fo="; 37 | depsHash = "sha256-B8kZKC1FilK/wWNzlrQgDVj+T0EhScK2o2lAtFK8FqY="; 38 | }; 39 | plugin-url = pluginBase { 40 | name = "url"; 41 | version = "v1.1.0"; 42 | srcHash = "sha256-7YiiPDjQr6vN933svHwz1yK3PdWTsY2SeJsw+PBv+zY="; 43 | depsHash = "sha256-B8kZKC1FilK/wWNzlrQgDVj+T0EhScK2o2lAtFK8FqY="; 44 | }; 45 | plugin-hideme = pluginBase { 46 | name = "hideme"; 47 | version = "v1.1.0"; 48 | srcHash = "sha256-tGAesHIGmdlp2PCTfX5zrikqjD9ZiQ+0tLsJFGiWwPQ="; 49 | depsHash = "sha256-B8kZKC1FilK/wWNzlrQgDVj+T0EhScK2o2lAtFK8FqY="; 50 | }; 51 | plugin-dump = pluginBase { 52 | name = "dump"; 53 | version = "v1.0.1"; 54 | srcHash = ""; 55 | depsHash = ""; 56 | }; 57 | plugin-native = pluginBase { 58 | name = "native"; 59 | version = "v1.0.0"; 60 | srcHash = ""; 61 | depsHash = ""; 62 | }; 63 | plugin-power = pluginBase { 64 | name = "power"; 65 | version = "v1.1.0"; 66 | srcHash = "sha256-sTjHvpQYF6soRIDhPspCdLYqLfZwPCjERq1EhIvX9z0="; 67 | depsHash = "sha256-S5SnS27x+vTwHd8Z6J8dO/wgThQClkgQv1WPJkFiyK8="; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /packages/java/default.nix: -------------------------------------------------------------------------------- 1 | { lib, pkgs, fetchurl, graalvmCEPackages 2 | , systems ? [ "aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux" ] 3 | }: 4 | let 5 | temurinSources = lib.importJSON ./temurin-sources.json; 6 | graalvmCeSources = lib.importJSON ./graalvm-ce-sources.json; 7 | 8 | mkJava = opts: 9 | pkgs.callPackage (import 10 | "${pkgs.path}/pkgs/development/compilers/temurin-bin/jdk-linux-base.nix" 11 | opts) { }; 12 | 13 | mkBorkedGraalVmCe = { url, sha256, version, javaVersion }: 14 | (graalvmCEPackages.buildGraalvm { 15 | inherit version; 16 | javaVersion = toString javaVersion; 17 | src = fetchurl { inherit url sha256; }; 18 | meta.platforms = systems; 19 | }).overrideAttrs (self: super: { 20 | doInstallCheck = false; 21 | # Make sure that `native-image` exists so that `wrapProgram` 22 | # has something to do. 23 | preInstall = '' 24 | touch $out/bin/native-image 25 | chmod +x $out/bin/native-image 26 | '' + (super.preInstall or ""); 27 | # Remove the `native-image` wrapper and the original empty file. 28 | postFixup = (super.postFixup or "") + '' 29 | rm $out/bin/native-image* 30 | ''; 31 | }); 32 | 33 | graalvmPlatform = let 34 | os = if pkgs.hostPlatform.isDarwin then 35 | "darwin" 36 | else if pkgs.hostPlatform.isLinux then 37 | "linux" 38 | else 39 | abort "GraalVM is not available for your OS"; 40 | arch = if pkgs.hostPlatform.isAarch64 then 41 | "aarch64" 42 | else if pkgs.hostPlatform.is64bit then 43 | "amd64" 44 | else 45 | abort "GraalVM does not support your CPU architecture"; 46 | in "${os}-${arch}"; 47 | 48 | in lib.makeExtensible (self: { 49 | temurin20-jre-bin = mkJava { sourcePerArch = temurinSources.openjdk20; }; 50 | graalvm8-ce = mkBorkedGraalVmCe graalvmCeSources.java8.${graalvmPlatform}; 51 | graalvm8-ce-jre = "${self.graalvm8-ce}/jre"; 52 | }) 53 | -------------------------------------------------------------------------------- /packages/java/graalvm-ce-sources.json: -------------------------------------------------------------------------------- 1 | { 2 | "java8": { 3 | "linux-amd64": { 4 | "javaVersion": 8, 5 | "version": "21.3.1", 6 | "url": "https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.3.1/graalvm-ce-java8-linux-amd64-21.3.1.tar.gz", 7 | "sha256": "sha256-uey9VC3h7Qo9pGpinyJmqIIDJpj1/LxU2JI3K5GJsO0=" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/java/temurin-sources.json: -------------------------------------------------------------------------------- 1 | { 2 | "openjdk20": { 3 | "packageType": "jre", 4 | "vmType": "hotspot", 5 | "x86_64": { 6 | "build": "9", 7 | "sha256": "e3592e86290c192804d9c6b5035d42cc32cf04141d1c0b9d1ecb67739826c8c5", 8 | "url": "https://github.com/adoptium/temurin20-binaries/releases/download/jdk-20.0.2%2B9/OpenJDK20U-jre_x64_linux_hotspot_20.0.2_9.tar.gz", 9 | "version": "20.0.2" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/json2nix.nix: -------------------------------------------------------------------------------- 1 | # This is a wrapper for `../scripts/json2nix.sh`. 2 | { pkgs, lib, nix, nixfmt-classic, ... }: 3 | pkgs.patchShellScript ../scripts/json2nix.sh rec { 4 | name = "json2nix"; 5 | destination = "/bin/${name}"; 6 | runtimeInputs = [ nix nixfmt-classic ]; 7 | } 8 | -------------------------------------------------------------------------------- /packages/lib/default.nix: -------------------------------------------------------------------------------- 1 | # FIXME export this somewhere 2 | { callPackage }: { # # 3 | wrapperTools = callPackage ./wrapper-tools.nix { }; 4 | } 5 | -------------------------------------------------------------------------------- /packages/lib/wrapper-tools.nix: -------------------------------------------------------------------------------- 1 | { makeSetupHook, writeScript, writeText, runtimeShell }: 2 | let 3 | hookScript = writeScript "wrapper-tools-setup-hook.in" '' 4 | #!@shell@ 5 | 6 | customWrapper() { 7 | local prog="$1" 8 | local wrapper="$2" 9 | local hidden 10 | 11 | assertExecutable "$prog" 12 | 13 | hidden="$(dirname "$prog")/.$(basename "$prog")-wrapped" 14 | while [ -e "$hidden" ]; do 15 | hidden+='_' 16 | done 17 | mv "$prog" "$hidden" 18 | 19 | cp "$wrapper" "$prog" 20 | chmod +x "$prog" 21 | patchShebangs "$prog" 22 | substituteInPlace "$prog" \ 23 | --subst-var-by 'shell' '@shell@' \ 24 | --subst-var-by 'helpers' '@helpers@' \ 25 | --subst-var-by 'program' "$hidden" 26 | } 27 | ''; 28 | helperScript = writeText "wrapper-tools-helpers" '' 29 | # shellcheck shell=bash 30 | 31 | # This script is not intended to be run standalone. 32 | # Use the `source` command in your custom wrapper 33 | # to gain access to these functions. 34 | 35 | trimPath() { 36 | local var="$1" 37 | local sep="$2" 38 | eval "$var=\"\''${$var%$sep}\"" 39 | eval "$var=\"\''${$var#$sep}\"" 40 | } 41 | 42 | prefixPath() { 43 | local var="$1" 44 | local sep="$2" 45 | local value="$3" 46 | eval "$var='$value$sep'\"\$$var\"" 47 | trimPath "$var" "$sep" 48 | } 49 | 50 | suffixPath() { 51 | local var="$1" 52 | local sep="$2" 53 | local value="$3" 54 | eval "$var+='$sep$value'" 55 | trimPath "$var" "$sep" 56 | } 57 | ''; 58 | in makeSetupHook { 59 | name = "custom-wrapper-hook"; 60 | substitutions = { 61 | shell = runtimeShell; 62 | helpers = helperScript; 63 | }; 64 | passthru.helpers = helperScript; 65 | } hookScript 66 | -------------------------------------------------------------------------------- /packages/nerdfonts.nix: -------------------------------------------------------------------------------- 1 | { stdenvNoCC, fetchzip }: 2 | stdenvNoCC.mkDerivation (self: { 3 | pname = "nerdfonts-symbols"; 4 | version = "3.0.2"; 5 | src = fetchzip { 6 | url = 7 | "https://github.com/ryanoasis/nerd-fonts/releases/download/v${self.version}/NerdFontsSymbolsOnly.tar.xz"; 8 | sha256 = "sha256-clfxFE1MvBUKn3NR/3WxW08R/4HZy0qZZi+S4Pt6WvI="; 9 | stripRoot = false; 10 | }; 11 | phases = [ "unpackPhase" "installPhase" ]; 12 | installPhase = '' 13 | runHook preInstall 14 | mkdir -p $out/share/fonts/truetype 15 | cp ./SymbolsNerdFont{,Mono}-Regular.ttf $out/share/fonts/truetype 16 | runHook postInstall 17 | ''; 18 | }) 19 | -------------------------------------------------------------------------------- /packages/overlays.nix: -------------------------------------------------------------------------------- 1 | lib: { 2 | # INDIVIDUAL PACKAGES # 3 | 4 | amdctl = pkgs: _: { # # 5 | amdctl = pkgs.callPackage ./amdctl.nix { }; 6 | }; 7 | 8 | ja-netfilter = pkgs: _: { 9 | ja-netfilter = pkgs.callPackage ./ja-netfilter { inherit lib; }; 10 | }; 11 | 12 | prtsc = pkgs: _: { # # 13 | prtsc = pkgs.callPackage ./prtsc { inherit lib; }; 14 | }; 15 | 16 | ttf-ms-win11 = pkgs: _: { 17 | ttf-ms-win11 = pkgs.callPackage ./ttf-ms-win11 { inherit lib; }; 18 | }; 19 | 20 | fork-awesome = pkgs: _: { 21 | fork-awesome = pkgs.callPackage ./fork-awesome.nix { inherit lib; }; 22 | }; 23 | 24 | idlehack = pkgs: _: { 25 | idlehack = pkgs.callPackage ./idlehack.nix { inherit lib; }; 26 | }; 27 | 28 | proton-ge-custom = pkgs: _: { 29 | proton-ge-custom = pkgs.callPackage ./proton-ge-custom.nix { inherit lib; }; 30 | }; 31 | 32 | nerdfonts-symbols = pkgs: _: { 33 | nerdfonts-symbols = pkgs.callPackage ./nerdfonts-symbols { inherit lib; }; 34 | }; 35 | 36 | java = pkgs: _: { 37 | inherit (pkgs.callPackage ./java { inherit lib; }) 38 | temurin20-jre-bin graalvm8-ce graalvm8-ce-jre; 39 | }; 40 | 41 | wavefox = pkgs: _: { 42 | wavefox = pkgs.callPackage ./wavefox.nix { inherit lib; }; 43 | }; 44 | 45 | # PACKAGE SETS # 46 | 47 | zsh-plugins = pkgs: _: { 48 | zsh-plugins = pkgs.callPackages ./zsh-plugins.nix { inherit lib; }; 49 | }; 50 | 51 | firefox-extensions = pkgs: _: { 52 | firefox-extensions = 53 | pkgs.callPackages ./firefox-extensions.nix { inherit lib; }; 54 | }; 55 | 56 | # SCOPED PACKAGES 57 | 58 | platformio-python = _: pkgs0: { 59 | python3Packages = pkgs0.python3Packages.overrideScope 60 | (ps: _: { platformio = ps.callPackage ./platformio-python.nix { }; }); 61 | }; 62 | 63 | # SCRIPTS # 64 | 65 | json2nix = pkgs: _: { 66 | json2nix = pkgs.callPackage ./json2nix.nix { inherit lib; }; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /packages/proton-ge-custom.nix: -------------------------------------------------------------------------------- 1 | # building from source is way too hard 2 | { stdenvNoCC, fetchzip, }: 3 | stdenvNoCC.mkDerivation (self: { 4 | name = "proton-ge-custom"; 5 | version = "GE-Proton7-49"; 6 | src = fetchzip { 7 | url = 8 | "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/${self.version}/${self.version}.tar.gz"; 9 | sha256 = "1wwxh0yk78wprfi1h9n7jf072699vj631dl928n10d61p3r90x82"; 10 | }; 11 | preferLocalBuild = true; 12 | installPhase = '' 13 | mkdir -p $out/${self.version} 14 | cp -r * $out/${self.version} 15 | ''; 16 | }) 17 | -------------------------------------------------------------------------------- /packages/prtsc/default.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv, makeBinaryWrapper, coreutils, perl, wl-clipboard, slurp, grim, ... }: 2 | stdenv.mkDerivation { 3 | pname = "prtsc"; 4 | version = "0.0.1"; 5 | 6 | strictDeps = true; 7 | 8 | src = ./.; 9 | 10 | nativeBuildInputs = [ makeBinaryWrapper ]; 11 | 12 | installPhase = '' 13 | runHook preInstall 14 | 15 | install -Dm755 ./prtsc.pl $out/bin/prtsc.pl 16 | 17 | runHook postInstall 18 | ''; 19 | 20 | postInstall = '' 21 | makeWrapper ${lib.getExe perl} $out/bin/prtsc \ 22 | --add-flags "$out/bin/prtsc.pl" \ 23 | --set PATH \ 24 | "${lib.makeBinPath [ coreutils wl-clipboard slurp grim ]}" 25 | ''; 26 | 27 | meta = { 28 | description = "Simple screenshot utility for Wayland"; 29 | license = lib.licenses.mit; 30 | platforms = lib.platforms.linux; 31 | maintainers = with lib.maintainers; [ spikespaz ]; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /packages/wavefox.nix: -------------------------------------------------------------------------------- 1 | { lib, stdenv, fetchFromGitHub }: 2 | stdenv.mkDerivation (self: { 3 | pname = "wavefox-userchrome"; 4 | version = "1.8.138-unstable"; 5 | src = fetchFromGitHub { 6 | owner = "QNetITQ"; 7 | repo = "WaveFox"; 8 | # Using this to respect `browser.tabs.tabMinWidth`. 9 | rev = "b8edea63e6543267ee498ec976020f991199eca6"; 10 | hash = "sha256-wANcp1ZlZJDoFYwpfp/R63VdRvmhaBL+TgoReSuC11U="; 11 | }; 12 | installPhase = '' 13 | mkdir $out 14 | cp -r $src/chrome -T $out 15 | cp -r $src/{README.md,LICENSE} -t $out 16 | ''; 17 | }) 18 | -------------------------------------------------------------------------------- /packages/zsh-plugins.nix: -------------------------------------------------------------------------------- 1 | # 1. If a plugin name starts with `zsh-`, leave it alone. 2 | # 2. If a plugin name ends with `-zsh`, remove it and prepend `zsh-`. 3 | # 3. If a plugin name does not contain `zsh`, prefix with `zsh-`. 4 | # 4. In all cases, leave `pname` so that it 5 | # matches the original name of the plugin. 6 | { lib, fetchFromGitHub }: 7 | let 8 | mkZshPlugin = { pname, version, meta ? { }, src }: 9 | src.overrideAttrs (self: super: { 10 | inherit pname version; 11 | name = "${pname}-${version}"; 12 | meta = super.meta 13 | // (lib.optionalAttrs (src ? meta && src.meta ? homepage) { 14 | homepage = src.meta.homepage; 15 | }) // meta; 16 | }); 17 | in lib.recurseIntoAttrs { 18 | zsh-autosuggestions = mkZshPlugin rec { 19 | pname = "zsh-autosuggestions"; 20 | version = "v0.7.0"; 21 | src = fetchFromGitHub { 22 | owner = "zsh-users"; 23 | repo = pname; 24 | rev = version; 25 | hash = "sha256-KLUYpUu4DHRumQZ3w59m9aTW6TBKMCXl2UcKi4uMd7w="; 26 | }; 27 | meta.license = lib.licenses.mit; 28 | }; 29 | zsh-autocomplete = mkZshPlugin rec { 30 | pname = "zsh-autocomplete"; 31 | version = "23.07.13"; 32 | src = fetchFromGitHub { 33 | owner = "marlonrichert"; 34 | repo = pname; 35 | rev = version; 36 | hash = "sha256-0NW0TI//qFpUA2Hdx6NaYdQIIUpRSd0Y4NhwBbdssCs="; 37 | }; 38 | meta.license = lib.licenses.mit; 39 | }; 40 | zsh-edit = mkZshPlugin rec { 41 | pname = "zsh-edit"; 42 | version = "unstable-2023-05-13"; 43 | src = fetchFromGitHub { 44 | owner = "marlonrichert"; 45 | repo = pname; 46 | rev = "9eb286982f96f03371488e910e42afb23802bdfd"; 47 | hash = "sha256-LVHkH7fi8BQxLSeV+osdZzar1PQ0/hdb4yZ4oppGBoc="; 48 | }; 49 | meta.license = lib.licenses.mit; 50 | }; 51 | zsh-autopair = mkZshPlugin rec { 52 | pname = "zsh-autopair"; 53 | version = "unstable-2022-10-03"; 54 | src = fetchFromGitHub { 55 | owner = "hlissner"; 56 | repo = pname; 57 | rev = "396c38a7468458ba29011f2ad4112e4fd35f78e6"; 58 | hash = "sha256-PXHxPxFeoYXYMOC29YQKDdMnqTO0toyA7eJTSCV6PGE="; 59 | }; 60 | meta.license = lib.licenses.mit; 61 | }; 62 | zsh-auto-notify = mkZshPlugin rec { 63 | pname = "zsh-auto-notify"; 64 | version = "unstable-2023-06-02"; 65 | src = fetchFromGitHub { 66 | owner = "MichaelAquilina"; 67 | repo = pname; 68 | rev = "22b2c61ed18514b4002acc626d7f19aa7cb2e34c"; 69 | hash = "sha256-x+6UPghRB64nxuhJcBaPQ1kPhsDx3HJv0TLJT5rjZpA="; 70 | }; 71 | meta.license = lib.licenses.gpl3; 72 | }; 73 | zsh-window-title = mkZshPlugin rec { 74 | pname = "zsh-window-title"; 75 | version = "v1.0.2"; 76 | src = fetchFromGitHub { 77 | owner = "olets"; 78 | repo = pname; 79 | rev = version; 80 | hash = "sha256-efLpDY+cIe2KhRFpTcm85mYUFlTa2ECTIFhP7hjuf+8="; 81 | }; 82 | # Actually some cobbled-together license with most parts from: 83 | meta.license = lib.licenses.cc-by-nc-sa-40; 84 | }; 85 | zsh-fast-syntax-highlighting = mkZshPlugin rec { 86 | pname = "fast-syntax-highlighting"; 87 | version = "unstable-2023-07-05"; 88 | src = fetchFromGitHub { 89 | owner = "zdharma-continuum"; 90 | repo = pname; 91 | rev = "cf318e06a9b7c9f2219d78f41b46fa6e06011fd9"; 92 | hash = "sha256-RVX9ZSzjBW3LpFs2W86lKI6vtcvDWP6EPxzeTcRZua4="; 93 | }; 94 | meta.license = lib.licenses.bsd3; 95 | }; 96 | } 97 | -------------------------------------------------------------------------------- /scripts/airplane-mode.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | set -x 4 | 5 | if [[ $UID -ne 0 ]]; then 6 | sudo "$0" "$@" 7 | exit $? 8 | fi 9 | 10 | if [[ "$1" = toggle ]]; then 11 | if [[ ! -f /var/lib/airplane-mode.state ]]; then 12 | echo 0 > /var/lib/airplane-mode.state 13 | state=0 14 | else 15 | state=$(cat /var/lib/airplane-mode.state) 16 | "$0" $(($state == 1 ? 0 : 1)) 17 | fi 18 | elif [[ "$1" -eq 1 ]]; then 19 | systemctl stop iwd.service 20 | systemctl stop bluetooth.service 21 | rfkill block all 22 | echo 1 > /var/lib/airplane-mode.state 23 | elif [[ "$1" -eq 0 ]]; then 24 | rfkill unblock all 25 | systemctl restart iwd.service 26 | systemctl restart bluetooth.service 27 | echo 0 > /var/lib/airplane-mode.state 28 | else 29 | echo 'missing arg: 0 for off, 1 for on, or toggle' 30 | fi 31 | -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | set -eu 3 | 4 | confirm=1 5 | target='/mnt' 6 | pool='intrepid' 7 | unmount=0 8 | disable_cache=0 9 | 10 | help_message="$( 11 | cat <<- EOF 12 | Synopsis: 13 | Use this script after partitioning to recursively unmount the target, 14 | invalidate zpool cache, and export the pool to ensure that the pool 15 | can be imported without forcing after a reboot. 16 | 17 | Usage: 18 | $(basename "$0") [-y][-h][-t

][-p ][-u][-c] 19 | 20 | Options: 21 | -y | --no-confirm 22 | Skip confirmation and performs changes immediately. 23 | -h | --help 24 | Display this help message. 25 | -t | --target 26 | Specify an alternate path to the root of a filesystem, 27 | for example '/mnt' or '/target'. 28 | -p