diff --git a/Extras/Screenshots/SecondUnix.png b/Extras/Screenshots/SecondUnix.png
new file mode 100644
index 0000000..08da742
Binary files /dev/null and b/Extras/Screenshots/SecondUnix.png differ
diff --git a/Extras/Wallpapers/lockpaper.png b/Extras/Wallpapers/lockpaper.png
new file mode 100644
index 0000000..0d97584
Binary files /dev/null and b/Extras/Wallpapers/lockpaper.png differ
diff --git a/Extras/Wallpapers/wallpaper1.png b/Extras/Wallpapers/wallpaper1.png
new file mode 100644
index 0000000..dfa5537
Binary files /dev/null and b/Extras/Wallpapers/wallpaper1.png differ
diff --git a/Extras/Wallpapers/wallpaper2.png b/Extras/Wallpapers/wallpaper2.png
new file mode 100644
index 0000000..70a632a
Binary files /dev/null and b/Extras/Wallpapers/wallpaper2.png differ
diff --git a/Extras/Wallpapers/wallpaper3.png b/Extras/Wallpapers/wallpaper3.png
new file mode 100644
index 0000000..0d3e6c7
Binary files /dev/null and b/Extras/Wallpapers/wallpaper3.png differ
diff --git a/PC/configuration.nix b/PC/configuration.nix
new file mode 100644
index 0000000..1c22efe
--- /dev/null
+++ b/PC/configuration.nix
@@ -0,0 +1,411 @@
+{ config, pkgs, options, lib, ... }:
+let
+ # Import home manager, set common boot paramaters
+ homeManager = fetchTarball
+ "https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz";
+ commonKernelParams = [
+ # Nvidia GSP firmware
+ "nouveau.config=NvGspRm=1"
+
+ # VM/GPU passthrough
+ "amd_iommu=on"
+ "iommu=pt"
+ "nested=1"
+
+ # Virtualization nonsense
+ "transparent_hugepage=never"
+
+ # Isolate devices into IOMMU groups
+ "pcie_acs_override=downstream,multifunction"
+ "pci=routeirq"
+ ];
+in
+
+{
+ # Import other nix files and firmware
+ imports = [
+ ./hardware-configuration.nix
+ ./jimbo.nix
+ "${homeManager}/nixos"
+ ];
+
+ # Allow unfree packages and accept packages from the Nix User Repos
+ nixpkgs = {
+ config = {
+ allowUnfree = true;
+ packageOverrides = pkgs: {
+ unstable = import (builtins.fetchTarball
+ "https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz") {
+ inherit pkgs;
+ config.allowUnfree = true;
+ };
+ };
+ };
+
+ # Package overlays/patches
+ overlays = [
+ # MPV scripts
+ (self: super: {
+ mpv = super.mpv.override {
+ scripts = with self.mpvScripts;
+ [ mpris sponsorblock thumbnail ];
+ };
+ })
+ ];
+ };
+
+ # Allow flakes and enable garbage collection
+ nix = {
+ settings.experimental-features = [ "nix-command" "flakes" ];
+ gc = {
+ automatic = true;
+ dates = "weekly";
+ options = "--delete-older-than 14d";
+ };
+ };
+
+ # Set all boot options
+ boot = {
+ # Set a kernel version and load/blacklist drivers
+ kernelPackages = pkgs.linuxPackages_xanmod_latest;
+ blacklistedKernelModules = [ "pcspkr" ];
+ kernelParams = commonKernelParams ++ [ "vfio-pci.ids=10de:13c2,10de:0fbb" ];
+ initrd.kernelModules = [ "vfio" "vfio_pci" "vfio_iommu_type1" ];
+
+ # Manage supported filesystems
+ supportedFilesystems = {
+ ntfs = true;
+ zfs = lib.mkForce false;
+ };
+
+ # Modprobe settings
+ extraModprobeConfig = ''
+ options hid_apple fnmode=2
+ '';
+
+ # Use the Systemd-Boot bootloader
+ loader.systemd-boot = {
+ enable = true;
+ netbootxyz.enable = true;
+ };
+ };
+
+ # Add a kernel entry to boot from the secondary GPU
+ specialisation = {
+ gputwo.configuration = {
+ boot.kernelParams = commonKernelParams ++ [ "vfio-pci.ids=10de:2504,10de:228e" ];
+ };
+ };
+
+ # Allow binary firmware
+ hardware.enableRedistributableFirmware = true;
+
+ # Enable the Nouveau drivers
+ services.xserver.videoDrivers = [ "nouveau" ];
+
+ # Enable a permissioning system
+ security = {
+ sudo.enable = false;
+ doas = {
+ enable = true;
+ extraRules = [
+ # Give wheel root access, allow persistant session
+ { groups = [ "wheel" ]; keepEnv = true; persist = true; }
+ ];
+ };
+ };
+
+ # Enable the ZSH shell
+ programs.zsh.enable = true;
+
+ # Disable Nano
+ programs.nano.enable = false;
+
+ # Timezone
+ time.timeZone = "America/New_York";
+
+ # Define a user account
+ users.users.jimbo = {
+ description = "Jimbo Awesome";
+ isNormalUser = true;
+ hashedPassword =
+ "$6$gYpE.pG/zPXgin06$2kydjDfd0K62Dhf9P0PFvJhRNz6xIC/bHYaf/XYqyKcLyZNzPQpy8uy9tCRcSYlj1wwBhzVtTRyItwajOHCEj0";
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDLe/HioxCOkszFQdm1vb3ZwuzLzsOThqHNvEI4IXeXZ JimPhone"
+ ];
+ extraGroups = [
+ "wheel" "audio" "video" "input" "disk" "dialout"
+ "networkmanager" "kvm" "libvirtd" "qemu-libvirtd"
+ ];
+ uid = 1000;
+ shell = pkgs.zsh;
+ };
+
+ # Installed programs to the system profile.
+ environment.systemPackages = with pkgs; [
+ # Essential system tools
+ cifs-utils parted git
+
+ # Printer control
+ system-config-printer
+
+ # Virtual machines
+ virt-manager virtiofsd dnsmasq
+ spice-vdagent looking-glass-client
+ ];
+
+ # Disable the HTML documentation link
+ documentation = {
+ nixos.enable = false;
+ info.enable = false;
+ };
+
+ # Enable OpenGL
+ hardware.opengl = {
+ enable = true;
+ package = pkgs.unstable.mesa.drivers;
+ package32 = pkgs.unstable.pkgsi686Linux.mesa.drivers;
+ driSupport = true;
+ driSupport32Bit = true;
+ extraPackages = with pkgs; [
+ vulkan-loader
+ vulkan-validation-layers
+ vulkan-extension-layer
+ ];
+ };
+
+ # Enable Steam hardware and gamemode
+ hardware.steam-hardware.enable = true;
+ programs.gamemode.enable = true;
+
+ # Networking settings
+ networking = {
+ # Set hostname
+ hostName = "JimNixPC";
+
+ # Choose networking method
+ dhcpcd.enable = true;
+ wireless.enable = false;
+ #networkmanager.enable = true;
+ #enableB43Firmware = true;
+
+ # Enable firewall passthrough
+ firewall = {
+ allowedTCPPorts = [
+ # Sunshine TCP
+ 47984 47989 48010
+ ];
+ allowedUDPPorts = [
+ # Sunshine UDP
+ 47998 47999 48000
+
+ # Games
+ 27005 27015 7777
+ ];
+ allowPing = false;
+ };
+ extraHosts = ''
+ 192.168.1.18 pc
+ 192.168.1.17 server
+ 192.168.2.2 vm
+ '';
+ nameservers = [
+ "1.1.1.1"
+ "9.9.9.9"
+ ];
+ };
+
+ # Enable Bluetooth
+ hardware.bluetooth = {
+ enable = true;
+ settings = {
+ General.Experimental = "true";
+ Policy.AutoEnable = "true";
+ };
+ };
+
+ # Enable lingering for Bluetooth and allow Looking-Glass permissions
+ systemd.tmpfiles.rules = [
+ "f /var/lib/systemd/linger/jimbo"
+ "f /dev/shm/looking-glass 0660 jimbo libvirtd -"
+ ];
+
+ # Make udev rules to make PDP controller and Oculus Rift CV1 work
+ services.udev = let
+ oculusRules = pkgs.writeTextFile {
+ name = "10-oculus.rules";
+ text = ''
+ KERNEL=="hidraw*", ATTRS{idVendor}=="0e6f", ATTRS{idProduct}=="0184", MODE="0660", TAG+="uaccess"
+ '';
+ destination = "/etc/udev/rules.d/10-oculus.rules";
+ };
+ pdpRules = pkgs.writeTextFile {
+ name = "10-pdp.rules";
+ text = ''
+ SUBSYSTEM=="usb", ATTR{idVendor}=="2833", MODE="0666", GROUP="plugdev"
+ '';
+ destination = "/etc/udev/rules.d/10-pdp.rules";
+ };
+ in {
+ packages = [ oculusRules pdpRules ];
+ };
+
+ # Enable audio
+ security.rtkit.enable = true;
+ hardware.pulseaudio.enable = false;
+ services.pipewire = {
+ enable = true;
+ alsa.enable = true;
+ alsa.support32Bit = true;
+ pulse.enable = true;
+ #jack.enable = true;
+ };
+
+ # Fonts
+ fonts = {
+ packages = with pkgs; [
+ liberation_ttf twitter-color-emoji ubuntu_font_family noto-fonts sarasa-gothic
+ orbitron (nerdfonts.override { fonts = [ "UbuntuMono" ]; })
+ ];
+ fontconfig.defaultFonts.emoji = [ "Twitter Color Emoji" ];
+ };
+
+ # Enable Dconf and some portals
+ services.dbus.enable = true;
+ programs.dconf.enable = true;
+ programs.light.enable = true;
+ security.pam.services.swaylock = {};
+ xdg.portal = {
+ enable = true;
+ config.common.default = "*";
+ wlr = {
+ enable = true;
+ settings = {
+ screencast = {
+ max_fps = 60;
+ chooser_type = "simple";
+ chooser_cmd = "${pkgs.slurp}/bin/slurp -f %o -or -B 00000066 -b 00000099";
+ };
+ };
+ };
+ extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
+ };
+
+ # Configure greetd for remote login
+ services.greetd = {
+ enable = true;
+ restart = true;
+ settings = {
+ terminal = {
+ vt = 2;
+ switch = true;
+ };
+ default_session = {
+ command = "/home/jimbo/.config/sway/start.sh";
+ user = "jimbo";
+ };
+ };
+ };
+
+ # QT theming
+ qt = {
+ enable = true;
+ style = "gtk2";
+ platformTheme = "gtk2";
+ };
+
+ # Enable printing
+ services = {
+ printing = {
+ enable = true;
+ drivers = with pkgs; [ hplip ];
+ webInterface = false;
+ };
+ avahi = {
+ enable = true;
+ nssmdns4 = true;
+ openFirewall = true;
+ };
+ };
+
+ # Enable virtualization
+ virtualisation = {
+ libvirtd = {
+ enable = true;
+ onBoot = "ignore";
+ onShutdown = "shutdown";
+ qemu = {
+ ovmf = {
+ enable = true;
+ packages = [ pkgs.OVMFFull.fd ];
+ };
+ swtpm.enable = true;
+ };
+ };
+ spiceUSBRedirection.enable = true;
+ };
+
+ # Enable SSH
+ services.openssh = {
+ enable = true;
+ settings = {
+ LogLevel = "VERBOSE";
+ PermitRootLogin = "no";
+ PrintLastLog = "no";
+ PasswordAuthentication = false;
+ };
+ ports = [ 2211 ];
+ };
+
+ # Block SSH connections after numerous attempts
+ services.fail2ban = {
+ enable = true;
+ maxretry = 10;
+ };
+
+ # Enable AppImages
+ programs.appimage = {
+ enable = true;
+ binfmt = true;
+ };
+
+ # Enable MPD
+ services.mpd = {
+ enable = true;
+ user = "jimbo";
+ group = "users";
+ musicDirectory = "/home/jimbo/JimboNFS/Music";
+ playlistDirectory = "/home/jimbo/JimboNFS/Music/Playlists";
+ extraConfig = ''
+ audio_output {
+ type "pipewire"
+ name "Local Pipewire"
+ }
+ '';
+ };
+ systemd.services.mpd.environment = {
+ XDG_RUNTIME_DIR = "/run/user/${toString config.users.users.jimbo.uid}";
+ };
+
+ # Enable AppArmor
+ security.apparmor.enable = true;
+
+ # Enable Polkit for authentication
+ security.polkit.enable = true;
+
+ # Battery saver for laptops
+ services.tlp.enable = true;
+
+ # Enable extra functionality in file managers
+ services.gvfs.enable = true;
+
+ # Attempt to automount USB drives
+ services.udisks2.enable = true;
+
+ # Used for Seneca VPN
+ services.globalprotect.enable = true;
+
+ # Define the initial install version and allow auto-upgrades
+ system.stateVersion = "23.11";
+ system.autoUpgrade.enable = true;
+}
diff --git a/PC/hardware-configuration.nix b/PC/hardware-configuration.nix
new file mode 100644
index 0000000..8ccb8c6
--- /dev/null
+++ b/PC/hardware-configuration.nix
@@ -0,0 +1,73 @@
+# This file was generated by 'nixos-generate-config'
+# and may be overwritten by future invocations.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+ imports = [
+ (modulesPath + "/installer/scan/not-detected.nix")
+ ];
+
+ # Load kernel modules on boot
+ boot = {
+ initrd = {
+ availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
+ kernelModules = [ ];
+ };
+ kernelModules = [ "kvm-amd" ];
+ extraModulePackages = [ ];
+ };
+
+ # Mount everything as necessary
+ fileSystems = {
+ "/" = {
+ device = "/dev/disk/by-uuid/f0786b07-8303-416f-87ff-276bfd696387";
+ fsType = "bcachefs";
+ };
+ "/boot" = {
+ device = "/dev/disk/by-uuid/EF6D-9009";
+ fsType = "vfat";
+ };
+ "/etc/libvirt" = {
+ device = "/dev/disk/by-label/Qemu";
+ options = [ "nosuid" "nodev" "nofail" ] ;
+ };
+ "/var/lib/libvirt" = {
+ depends = [ "/etc/libvirt" ];
+ device = "/etc/libvirt/varlibvirt";
+ options = [ "bind" "rw" ];
+ };
+ "/mnt/Linux1" = {
+ device = "/dev/disk/by-label/Linux1";
+ options = [ "nosuid" "nodev" "nofail" "x-gvfs-show" ];
+ };
+ "/mnt/Linux2" = {
+ device = "/dev/disk/by-label/Linux2";
+ options = [ "nosuid" "nodev" "nofail" "x-gvfs-show" ];
+ };
+ "/mnt/Windows1" = {
+ device = "/dev/disk/by-label/Windows1";
+ options = [ "nosuid" "nodev" "noauto" ];
+ };
+ "/mnt/Windows2" = {
+ device = "/dev/disk/by-label/Windows2";
+ options = [ "nosuid" "nodev" "noauto" ];
+ };
+ "/home/jimbo/JimboNFS" = {
+ device = "server:/export/JimboNFS";
+ fsType = "nfs";
+ options = [ "nofail" ];
+ };
+ };
+
+ # Set the swap partition
+ swapDevices = [
+ { device = "/dev/disk/by-uuid/2e4c5120-716d-4cdc-84a0-c9e6391760db"; }
+ ];
+
+ # Enables DHCP on each ethernet and wireless interface.
+ networking.useDHCP = lib.mkDefault true;
+ # networking.interfaces.enp42s0.useDHCP = lib.mkDefault true;
+
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/PC/jimbo.nix b/PC/jimbo.nix
new file mode 100644
index 0000000..65cf4e6
--- /dev/null
+++ b/PC/jimbo.nix
@@ -0,0 +1,3043 @@
+{ config, pkgs, options, ... }:
+let
+ # Global color palette
+ primeCol = ''3823C4''; #3823C4
+ accentCol = ''1B1F59''; #1B1F59
+ splitCol = ''555B9E''; #555B9E
+ actSplitCol = ''5980B7''; #5980B7
+ darkCol = ''101419''; #101419
+ midCol = ''171C23''; #171C23
+ lightCol = ''272b33''; #272B33
+ urgentCol = ''C43823''; #C43823
+ textCol = ''C7D3E3''; #C7D3E3
+
+ # Papirus icon theme color
+ folderCol = ''indigo'';
+
+ # Gtk theme
+ themeSettings = {
+ name = "Colloid-Dark";
+ package = pkgs.colloid-gtk-theme.override {
+ themeVariants = [ "default" ];
+ colorVariants = [ "dark" ];
+ sizeVariants = [ "standard" ];
+ tweaks = [ "black" "rimless" "normal" ];
+ };
+ };
+
+ # Wallpapers
+ wallpaper1 = pkgs.fetchurl {
+ url = "https://git.JimbosFiles.com/Jimbo/NixOS-Files/raw/branch/main/Extras/Wallpapers/wallpaper1.png";
+ sha256 = "1zxb0p0fjsmccy4xv8yk3c4kc313k3lc3xhqmiv452f7sjqqbp25";
+ };
+ wallpaper2 = pkgs.fetchurl {
+ url = "https://git.JimbosFiles.com/Jimbo/NixOS-Files/raw/branch/main/Extras/Wallpapers/wallpaper2.png";
+ sha256 = "13jcllrs05d26iz2isvh1f8fqf20m23sps32kw7qz5iav8nhvsx7";
+ };
+ wallpaper3 = pkgs.fetchurl {
+ url = "https://git.JimbosFiles.com/Jimbo/NixOS-Files/raw/branch/main/Extras/Wallpapers/wallpaper3.png";
+ sha256 = "16r65qnr7f0md4bbjnzq6av4dgmqr3avkilw72qdmyrmh3xj03yw";
+ };
+ lockpaper = pkgs.fetchurl {
+ url = "https://git.JimbosFiles.com/Jimbo/NixOS-Files/raw/branch/main/Extras/Wallpapers/lockpaper.png";
+ sha256 = "1mqvp4bic46gc994fawkraqj76hxd11wdd43qakligchzd20xjd5";
+ };
+
+ # Define the workspace names
+ w0 = ''0:0''; w1 = ''1:1''; w2 = ''2:2''; w3 = ''3:3''; w4 = ''4:4'';
+ w5 = ''5:5''; w6 = ''6:6''; w7 = ''7:7''; w8 = ''8:8''; w9 = ''9:9'';
+ w1a = ''11:I''; w2a = ''22:II''; w3a = ''33:III''; w4a = ''44:IV'';
+ w5a = ''55:V''; w6a = ''66:VI''; w7a = ''77:VII''; w8a = ''88:VIII''; w9a = ''99:IX'';
+
+ # Define the primary monitor
+ display1 = ''DP-3'';
+ display2 = ''DP-1'';
+ display3 = ''DP-2'';
+ displayTouch = ''eDP-1'';
+
+ # Define miscellaneous window manager properties
+ borderWeightInt = 3;
+ borderWeight = toString borderWeightInt;
+
+ # Set the font across all applications I can
+ mainFont = ''Ubuntu'';
+ nerdFont = ''UbuntuMono Nerd Font'';
+
+ # Terminal authentication
+ auth = ''doas'';
+
+ # Set the default terminal emulator
+ terminal = ''${pkgs.foot}/bin/foot'';
+ terminalClass = ''${terminal} -a'';
+ termPreviewMethod = ''sixel'';
+
+ # Bemenu color options
+ bemenuOpts = ''
+ --fn "${mainFont} 13" \
+ --tb "#${primeCol}" \
+ --hb "#${primeCol}" \
+ --nb "#${darkCol}" \
+ --ab "#${darkCol}" \
+ --fb "#${darkCol}" \
+ --tf "#ffffff" \
+ --hf "#ffffff" \
+ --ignorecase \
+ --hp 8 \
+ '';
+
+ # Sway still needs a start script because the sessionconfig doesn't do anything
+ swayStart = ''
+ # Use NVIDIA variables if drivers are in use
+ if lspci -k | grep "Kernel driver in use: nvidia" &> /dev/null; then
+ # NVIDIA/AMD variables
+ export LIBVA_DRIVER_NAME=nvidia
+ export GBM_BACKEND=nvidia-drm
+ export __GLX_VENDOR_LIBRARY_NAME=nvidia
+ export WLR_NO_HARDWARE_CURSORS=1
+ else
+ export WLR_RENDERER=vulkan
+ fi
+
+ # Sway/Wayland
+ export XDG_CURRENT_DESKTOP=sway
+ export QT_QPA_PLATFORM="wayland;xcb"
+
+ # Start Sway
+ sway --unsupported-gpu
+ '';
+
+ # Swappy config, for screenshot editing
+ swappyConfig = ''
+ [Default]
+ early_exit=true
+ save_dir=$HOME/Pictures/Screenshots
+ '';
+
+ # All my bemenu scripts in one file
+ beScripts = pkgs.writeScriptBin "bescripts" ''
+ # Scratchpad function
+ handle_scratchpads() {
+ SCRATCHPADS=$(echo -e "Gotop\nMusic\nPavuControl\nEasyEffects" | bemenu ${bemenuOpts} -p "Scratchpads")
+ case $SCRATCHPADS in
+ Gotop) ${terminalClass} gotop -T Gotop gotop;;
+ Music) ${terminalClass} music -T Music ncmpcpp;;
+ PavuControl) pavucontrol;;
+ EasyEffects) easyeffects;;
+ esac
+ }
+
+ # Lock menu
+ handle_power() {
+ POWER=$(echo -e "Shutdown\nReboot\nSleep\nLock\nKill" | bemenu ${bemenuOpts} -p "Power")
+ case $POWER in
+ Shutdown) poweroff;;
+ Reboot) reboot;;
+ Sleep) swaylock --sleep &;;
+ Lock) swaylock &;;
+ Kill) pkill -9 sway;;
+ esac
+ }
+
+ # Media launcher
+ handle_media() {
+ RET=$(echo -e "YouTube\nMusic\nHistory\nAnime" | bemenu ${bemenuOpts} -p "Media")
+ case $RET in
+ YouTube) ytfzf -D;;
+ Music) ytfzf -D -m;;
+ History) ytfzf -D -H;;
+ Anime) ${terminal} ani-cli -q 720;;
+ esac
+ }
+
+ # Resolutions
+ handle_resolutions() {
+ RET=$(echo -e "Default\nWide\nGPU2" | bemenu ${bemenuOpts} -p "Resolutions")
+ case $RET in
+ Default) swaymsg reload ;;
+ Wide) swaymsg "
+ output ${display1} enable pos 1680 0 mode 1680x1050@59.954Hz
+ output ${display2} enable pos 0 0 mode 1680x1050@59.954Hz
+ output ${display3} enable pos 3360 0 transform 0
+ ";;
+ GPU2) swaymsg "
+ output ${display2} enable pos 1680 0 mode 1920x1080@60Hz
+ output ${display3} enable pos 0 0 transform 0
+ ";;
+ esac
+ }
+
+ # Check for command-line arguments
+ if [ "$1" == "--scratchpads" ]; then
+ handle_scratchpads
+ elif [ "$1" == "--power" ]; then
+ handle_power
+ elif [ "$1" == "--media" ]; then
+ handle_media
+ elif [ "$1" == "--resolutions" ]; then
+ handle_resolutions
+ else
+ echo "Please use a valid argument."
+ fi
+ '';
+
+ # Swaylock's colors and background image
+ swayLock = pkgs.writeScriptBin "swaylock" ''
+ # Set the lock script
+ lockscript() {
+ BLANK='#00000000'
+ CLEAR='#FFFFFF22'
+ DEFAULT='#${primeCol}FF'
+ TEXT='#FFFFFFFF'
+ WRONG='#${splitCol}FF'
+ VERIFYING='#${accentCol}FF'
+
+ ${pkgs.swaylock-effects}/bin/swaylock -f -e \
+ --key-hl-color=$VERIFYING \
+ --bs-hl-color=$WRONG \
+ \
+ --ring-clear-color=$CLEAR \
+ --ring-ver-color=$VERIFYING \
+ --ring-wrong-color=$WRONG \
+ --ring-color=$DEFAULT \
+ --ring-clear-color=$VERIFYING \
+ \
+ --inside-color=$CLEAR \
+ --inside-ver-color=$CLEAR \
+ --inside-wrong-color=$CLEAR \
+ --inside-clear-color=$CLEAR \
+ \
+ --text-color=$TEXT \
+ --text-clear-color=$TEXT \
+ --text-ver-color=$TEXT \
+ --text-caps-lock-color=$TEXT \
+ --text-wrong-color=$TEXT \
+ \
+ --indicator \
+ --indicator-radius=80 \
+ --image=${lockpaper} \
+ --clock \
+ --font=${mainFont} \
+ --font-size=30 \
+ --timestr="%I:%M%p" \
+ --datestr="%a %b %d %Y"
+ }
+
+ # Handle whether to lock or sleep
+ if [ "$1" == "--sleep" ]; then
+ lockscript &
+ exec ${pkgs.swayidle}/bin/swayidle -w \
+ timeout 1 'swaymsg "output * dpms off"' \
+ resume 'swaymsg "output * dpms on"; pkill -9 swayidle'
+ else
+ lockscript
+ fi
+ '';
+
+ # Toggle notifications using mako
+ makoToggle = pkgs.writeScriptBin "makotoggle" ''
+ # Run makoctl mode and store the output in a variable
+ mode_output=$(makoctl mode)
+
+ # Extract the second line after "default"
+ mode_line=$(echo "$mode_output" | sed -n '/default/{n;p}')
+
+ if [[ "$mode_line" == "do-not-disturb" ]]; then
+ # Notifications are disabled, so we enable them
+ makoctl mode -r do-not-disturb
+ notify-send --expire-time=1500 'Notifications Enabled'
+ else
+ # Notifications are enabled, so we disable them
+ notify-send --expire-time=1500 'Notifications Disabled'
+ sleep 2
+ makoctl mode -a do-not-disturb
+ fi
+ '';
+
+ # Use grim and slurp to take screenshots in multiple ways
+ screenShot = pkgs.writeScriptBin "screenshot" ''
+ # Swappy
+ handle_swappy() {
+ # Create an imv window to act as a static screen
+ grim -t jpeg - | imv -w "GlobalShot" - & imv_pid=$!
+
+ # Capture the screenshot of the selected area and save to a temporary file
+ selected_area=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"'\
+ | XCURSOR_SIZE=40 slurp -w ${borderWeight} -c ${primeCol} -B 00000066 -b 00000099)
+ temp_file=$(mktemp -u).png
+ grim -g "$selected_area" "$temp_file"
+
+ # Kill the imv window
+ kill $imv_pid
+
+ # Copy the screenshot to the clipboard
+ swappy -f - < "$temp_file"
+
+ # Clean up the temporary file
+ rm "$temp_file"
+ }
+
+ # Current
+ handle_current() {
+ # Take a screenshot and save it to the temporary file
+ temp_file=$(mktemp -u).png
+ grim -o $(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name') "$temp_file"
+
+ # Check if the screenshot was successfully taken
+ if [ $? -eq 0 ]; then
+ # Copy the screenshot to the clipboard
+ wl-copy < "$temp_file"
+
+ # Show a notification with the screenshot
+ notify-send -i "$temp_file" "Current screen copied."
+
+ # Remove the temporary file
+ rm "$temp_file"
+ else
+ # If the screenshot capture failed, show an error notification
+ notify-send "Error: Unable to capture screenshot."
+ fi
+ }
+
+ # All screens
+ handle_all() {
+ # Take a screenshot and save it to the temporary file
+ temp_file=$(mktemp -u).png
+ grim -t jpeg "$temp_file"
+
+ # Check if the screenshot was successfully taken
+ if [ $? -eq 0 ]; then
+ # Copy the screenshot to the clipboard
+ wl-copy < "$temp_file"
+
+ # Show a notification with the screenshot
+ notify-send -i "$temp_file" "All screen copied."
+
+ # Remove the temporary file
+ rm "$temp_file"
+ else
+ # If the screenshot capture failed, show an error notification
+ notify-send "Error: Unable to capture screenshot."
+ fi
+ }
+
+ # Check for command-line arguments
+ if [ "$1" == "--swappy" ]; then
+ handle_swappy
+ elif [ "$1" == "--current" ]; then
+ handle_current
+ elif [ "$1" == "--all" ]; then
+ handle_all
+ else
+ echo "Please use the arguments swappy, current, or all."
+ fi
+ '';
+
+ # Handle all my alarms
+ alarmScript = let
+ alarmSound = pkgs.fetchurl {
+ url = "https://archive.org/download/espionage_202105/Espionage.mp3";
+ sha256 = "0y5b9ha6jrrar8shvilq1gcmrr37zf53f6zwba5c0m7yplbxnv65";
+ };
+ in pkgs.writeScriptBin "alarms" ''
+ # The alarm script itself
+ alarm() {
+ mpv --volume=40 --force-media-title="Alarm" ${alarmSound} &
+ swaynag \
+ --message "$name" \
+ --button "Stop Alarm" alarms \
+ --font ${mainFont} 12 --background ${darkCol} \
+ --border ${primeCol} \
+ --button-border-size ${borderWeight} \
+ --button-background ${darkCol} \
+ --border-bottom ${primeCol} \
+ --text ${textCol} \
+ --button-text ${textCol}
+ }
+
+ # Handle alarm times
+ handle_alarms() {
+
+ # Make the script loop when ran by Sway
+ while true; do
+ # Check the current day and time
+ current_day=$(date +"%A")
+ current_time=$(date +'%l:%M%p' | sed 's/^ //')
+
+ # Monday alarms
+ if [ "$current_day" == "Monday" ]; then
+ if [ "$current_time" == "7:30AM" ]; then
+ name="SEC 330 Physical"; alarm
+ fi
+ fi
+
+ # Tuesday alarms
+ if [ "$current_day" == "Tuesday" ]; then
+ if [ "$current_time" == "10:30AM" ]; then
+ name="DAT 330 Physical"; alarm
+ fi
+ fi
+
+ # Wednesday alarms
+ if [ "$current_day" == "Wednesday" ]; then
+ if [ "$current_time" == "6:30AM" ]; then
+ name="MST 300 Physical"; alarm
+ fi
+ fi
+
+ # Thursday alarms
+ if [ "$current_day" == "Thursday" ]; then
+ :
+ fi
+
+ # Friday alarms
+ if [ "$current_day" == "Friday" ]; then
+ if [ "$current_time" == "11:40AM" ]; then
+ name="DAT 330 Online"; alarm
+ fi
+ fi
+
+ # Wait a minute between checks
+ sleep 60
+ done
+ }
+
+ # Handle the killing of the alarm
+ kill_alarm() {
+ pkill -f 'mpv.*${alarmSound}'
+ pkill swaynag
+ }
+
+ # Check which mode the script is ran in
+ if [ "$1" == "--alarms" ]; then
+ handle_alarms
+ else
+ kill_alarm
+ fi
+ '';
+
+ # Check IOMMU Groups
+ iommuCheck = pkgs.writeScriptBin "lsiommu" ''
+ #!/usr/bin/env bash
+ shopt -s nullglob
+ for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
+ echo "IOMMU Group ''${g##*/}:"
+ for d in $g/devices/*; do
+ echo -e "\t$(lspci -nns ''${d##*/})"
+ done;
+ done;
+ '';
+
+ # File manager config
+ pcmanConf = ''
+ [Behavior]
+ BookmarkOpenMethod=current_tab
+ ConfirmDelete=true
+ RecentFilesNumber=0
+
+ [Desktop]
+ HideItems=false
+ SortColumn=name
+ SortFolderFirst=true
+ SortHiddenLast=false
+ SortOrder=ascending
+
+ [FolderView]
+ Mode=icon
+ ScrollPerPixel=true
+ ShadowHidden=true
+ ShowFilter=false
+ ShowFullNames=true
+ ShowHidden=true
+ SortCaseSensitive=false
+ SortColumn=mtime
+ SortFolderFirst=true
+ SortHiddenLast=false
+ SortOrder=descending
+
+ [Places]
+ HiddenPlaces=menu://applications/, network:///, computer:///, /home/jimbo/Desktop
+
+ [System]
+ Archiver=file-roller
+ Terminal=${terminal}
+
+ [Thumbnail]
+ MaxExternalThumbnailFileSize=-1
+ MaxThumbnailFileSize=4096
+ ShowThumbnails=true
+ ThumbnailLocalFilesOnly=true
+
+ [Window]
+ AlwaysShowTabs=false
+ PathBarButtons=true
+ ShowMenuBar=true
+ ShowTabClose=true
+ SwitchToNewTab=true
+ TabPaths=@Invalid()
+ '';
+
+ # Foot config
+ footConf = ''
+ font=${nerdFont}:size=14.7
+ term=xterm-256color
+
+ [cursor]
+ style=beam
+
+ [colors]
+ alpha=0.65
+ background=${darkCol}
+ regular0=3f3f3f
+ regular1=cc0000
+ regular2=4e9a06
+ regular3=c4a000
+ regular4=94bff3
+ regular5=85678f
+ regular6=06989a
+ regular7=dcdccc
+ bright0=545454
+ bright1=fc5454
+ bright2=8ae234
+ bright3=fce94f
+ bright4=94bff3
+ bright5=b294bb
+ bright6=93e0e3
+ bright7=ffffff
+
+ [key-bindings]
+ search-start=Control+f
+ '';
+
+ # Dashboard for my Debian server
+ serverDash = pkgs.writeScriptBin "serverdash" ''
+ ${terminalClass} serverdash ssh -p 2222 jimbo@server -t \
+ "tmux new-session -d -s control; tmux attach -t control"
+ '';
+
+ # An Easyeffects equalizer profile that sounds good to me
+ easyEffectsProfile = ''
+ {
+ "output": {
+ "blocklist": [],
+ "crystalizer#0": {
+ "band0": {
+ "bypass": false,
+ "intensity": 0.0,
+ "mute": false
+ },
+ "band1": {
+ "bypass": false,
+ "intensity": -1.0,
+ "mute": false
+ },
+ "band2": {
+ "bypass": false,
+ "intensity": -2.0,
+ "mute": false
+ },
+ "band3": {
+ "bypass": false,
+ "intensity": -3.0,
+ "mute": false
+ },
+ "band4": {
+ "bypass": false,
+ "intensity": -4.0,
+ "mute": false
+ },
+ "band5": {
+ "bypass": false,
+ "intensity": -5.0,
+ "mute": false
+ },
+ "band6": {
+ "bypass": false,
+ "intensity": -6.0,
+ "mute": false
+ },
+ "band7": {
+ "bypass": false,
+ "intensity": -7.0,
+ "mute": false
+ },
+ "band8": {
+ "bypass": false,
+ "intensity": -8.0,
+ "mute": false
+ },
+ "band9": {
+ "bypass": false,
+ "intensity": -9.0,
+ "mute": false
+ },
+ "band10": {
+ "bypass": false,
+ "intensity": -10.0,
+ "mute": false
+ },
+ "band11": {
+ "bypass": false,
+ "intensity": -11.0,
+ "mute": false
+ },
+ "band12": {
+ "bypass": false,
+ "intensity": -12.0,
+ "mute": false
+ },
+ "bypass": false,
+ "input-gain": 0.0,
+ "output-gain": 0.0
+ },
+ "equalizer#0": {
+ "balance": 0.0,
+ "bypass": false,
+ "input-gain": 0.0,
+ "left": {
+ "band0": {
+ "frequency": 32.0,
+ "gain": 1.1,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band1": {
+ "frequency": 64.0,
+ "gain": 1.16,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band2": {
+ "frequency": 125.0,
+ "gain": 3.33,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band3": {
+ "frequency": 250.0,
+ "gain": 1.53,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band4": {
+ "frequency": 500.0,
+ "gain": -1.83,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band5": {
+ "frequency": 1000.0,
+ "gain": -0.58,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band6": {
+ "frequency": 2000.0,
+ "gain": 1.42,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band7": {
+ "frequency": 4000.0,
+ "gain": 4.73,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band8": {
+ "frequency": 16000.0,
+ "gain": 7.62,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band9": {
+ "frequency": 156.38,
+ "gain": 2.84,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ }
+ },
+ "mode": "IIR",
+ "num-bands": 10,
+ "output-gain": 0.0,
+ "pitch-left": 0.0,
+ "pitch-right": 0.0,
+ "right": {
+ "band0": {
+ "frequency": 32.0,
+ "gain": 1.1,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band1": {
+ "frequency": 64.0,
+ "gain": 1.16,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band2": {
+ "frequency": 125.0,
+ "gain": 3.33,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band3": {
+ "frequency": 250.0,
+ "gain": 1.53,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band4": {
+ "frequency": 500.0,
+ "gain": -1.83,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band5": {
+ "frequency": 1000.0,
+ "gain": -0.58,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band6": {
+ "frequency": 2000.0,
+ "gain": 1.42,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band7": {
+ "frequency": 4000.0,
+ "gain": 4.73,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band8": {
+ "frequency": 16000.0,
+ "gain": 7.62,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ },
+ "band9": {
+ "frequency": 156.38,
+ "gain": 2.84,
+ "mode": "RLC (BT)",
+ "mute": false,
+ "q": 4.36,
+ "slope": "x1",
+ "solo": false,
+ "type": "Bell"
+ }
+ },
+ "split-channels": false
+ },
+ "plugins_order": [
+ "equalizer#0",
+ "crystalizer#0"
+ ]
+ }
+ }
+ '';
+
+ # Mangohud acts like rivatuner on Windows, config file
+ mangoConf = ''
+ table_columns=2
+ frametime=0
+ legacy_layout=0
+ font_scale=0.80
+ background_alpha=0.25
+
+ # Set the loads and such
+ exec=echo $(echo $XDG_CURRENT_DESKTOP | sed 's/./\U&/') on $(cat /etc/os-release | grep PRETTY_NAME | cut -d '"' -f 2)
+ fps
+ fps_color_change
+ ram
+ vram
+ cpu_stats
+ cpu_load_change
+ gpu_stats
+ gpu_load_change
+ frame_timing
+ '';
+
+ # Neofetch main config
+ neoConf = ''
+ {
+ "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+ "logo": {
+ "source": "xenia",
+ "color": {
+ "1": "1;97",
+ "2": "red",
+ "3": "yellow"
+ }
+ },
+ "display": {
+ "separator": " \u001b[33m ",
+ "color": "red"
+ },
+ "modules": [
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "host",
+ "format": "{5} {2}",
+ "key": " "
+ },
+ {
+ "type": "cpu",
+ "key": " "
+ },
+ {
+ "type": "gpu",
+ "key": " "
+ },
+ {
+ "type": "disk",
+ "folders": "/",
+ "key": " "
+ },
+ {
+ "type": "memory",
+ "format": "{/1}{-}{/}{/2}{-}{/}{} / {}",
+ "key": " "
+ },
+ {
+ "type": "display",
+ "compactType": "original",
+ "key": " "
+ },
+
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "os",
+ "format": "{3} {12}",
+ "key": " "
+ },
+ {
+ "type": "kernel",
+ "format": "{1} {2}",
+ "key": " "
+ },
+ {
+ "type": "wm",
+ "key": " "
+ },
+ {
+ "type": "shell",
+ "key": " "
+ },
+ {
+ "type": "terminal",
+ "key": " "
+ },
+ {
+ "type": "packages",
+ "key": " "
+ },
+ {
+ "type": "uptime",
+ "key": " "
+ },
+ {
+ "type": "command",
+ "text": "date -d @$(stat -c %W /) '+%a %b %d %r %Z %Y'",
+ "key": " "
+ },
+
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "custom",
+ "format": "\u001b[90m \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m"
+ }
+ ]
+ }
+ '';
+
+ # Small Neofetch config
+ pFetch = let
+ smallConf = pkgs.writeText "smallconf.jsonc" ''
+ {
+ "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+ "logo": {
+ "source": "nixos_small"
+ },
+ "modules": [
+ {
+ "type": "os",
+ "format": "{3} {12}",
+ "key": " "
+ },
+ {
+ "type": "host",
+ "format": "{5}",
+ "key": " "
+ },
+ {
+ "type": "kernel",
+ "format": "{1} {2}",
+ "key": " "
+ },
+ {
+ "type": "uptime",
+ "key": " "
+ },
+ {
+ "type": "packages",
+ "key": " "
+ },
+ {
+ "type": "memory",
+ "format": "{/1}{-}{/}{/2}{-}{/}{} / {}",
+ "key": " "
+ }
+ ]
+ }
+ '';
+ in pkgs.writeScriptBin "pfetch"
+ ''fastfetch --config ${smallConf}'';
+
+ # Ranger (terminal file browser) config
+ rangerConf = ''
+ set preview_script ~/.config/ranger/scope.sh
+ set preview_images true
+ set preview_images_method ${termPreviewMethod}
+ set dirname_in_tabs true
+ set cd_tab_fuzzy true
+ set autosave_bookmarks false
+ set show_hidden true
+ set wrap_scroll true
+ set column_ratios 2,2,4
+ set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$
+ default_linemode devicons
+ '';
+
+ # Choose which programs ranger uses
+ rifleConf = ''
+ # Websites
+ ext x?html?, has librewolf, X, flag f = librewolf -- "$@"
+
+ # Define the "editor" for text files as first action
+ mime ^text, label editor = vim -- "$@"
+ !mime ^text, label editor, ext xml|json|jsonc|m3u|m3u8|csv|tex|py|pl|rb|js|sh|php = vim -- "$@"
+
+ # Misc files
+ ext 1 = man "$1"
+ ext exe = wine "$1"
+ ext msi = wine "$1"
+ name ^[mM]akefile$ = make
+
+ # Scripts
+ ext sh = sh -- "$1"
+ ext py = python -- "$1"
+ ext pl = perl -- "$1"
+ ext rb = ruby -- "$1"
+ ext js = node -- "$1"
+ ext php = php -- "$1"
+
+ # Audio and video
+ mime ^audio|ogg$, terminal, has mpv = mpv --no-audio-display -- "$@"
+ mime ^audio|ogg$, terminal, has mpv = mpv --shuffle --no-audio-display -- "$@"
+ mime ^video, terminal, has mpv = mpv -- "$@"
+ mime ^video, terminal, has mpv = mpv --video-rotate=270 -- "$@"
+
+ # Documents
+ ext pdf, has zathura, X, flag f = zathura -- "$@"
+ ext pdf, has okular, X, flag f = okular -- "$@"
+ ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has libreoffice, X, flag f = libreoffice "$@"
+
+ # Images
+ mime ^image, has imv, X, flag f = imv -- "$@"
+
+ # Archives
+ ext 7z|ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz|iso|jar|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has 7z = 7z x -- "$@"
+
+ # Listing and extracting archives without atool:
+ ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | "$PAGER"
+ ext tar|gz|bz2|xz, has tar = for file in "$@"; do tar vvxf "$file"; done
+
+ # Fonts
+ mime ^font, has fontforge, X, flag f = fontforge "$@"
+
+ # Generic file openers
+ label open, has xdg-open = xdg-open -- "$@"
+
+ # Execute a file as program/script.
+ mime application/x-executable = "$1"
+ '';
+
+ # Ranger's preview
+ rangerScope = ''
+ #!/usr/bin/env bash
+ set -o noclobber -o noglob -o nounset -o pipefail
+ IFS=$'\n'
+
+ # Script arguments
+ FILE_PATH="$1"
+ PV_WIDTH="$2"
+ PV_HEIGHT="$3"
+ IMAGE_CACHE_PATH="$4"
+ PV_IMAGE_ENABLED="$5"
+
+ FILE_EXTENSION=$(echo "$FILE_PATH" | rev | cut -d. -f1 | rev)
+ FILE_EXTENSION_LOWER=$(echo "$FILE_EXTENSION" | tr '[:upper:]' '[:lower:]')
+
+ handle_extension() {
+ case "$FILE_EXTENSION_LOWER" in
+ # Archive
+ a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|iso|\
+ rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip|7z|rar)
+ 7z l -p -- "$FILE_PATH" && exit 5
+ exit 1;;
+ pdf)
+ pdftotext -l 10 -nopgbrk -q -- "$FILE_PATH" - && exit 5
+ exiftool "$FILE_PATH" && exit 5
+ exit 1;;
+ # OpenDocument
+ odt|ods|odp|sxw)
+ odt2txt "$FILE_PATH" && exit 5
+ exit 1;;
+ esac
+ }
+
+ handle_image() {
+ local mimetype="$1"
+ case "$mimetype" in
+ # SVG
+ image/svg+xml)
+ convert "$FILE_PATH" "$IMAGE_CACHE_PATH" && exit 6
+ exit 1;;
+ # Image
+ image/*)
+ local orientation
+ orientation="$( identify -format '%[EXIF:Orientation]\n' -- "$FILE_PATH" )"
+ if [[ -n "$orientation" && "$orientation" != 1 ]]; then
+ convert -- "$FILE_PATH" -auto-orient "$IMAGE_CACHE_PATH" && exit 6
+ fi
+ exit 7;;
+ # Video
+ video/*)
+ # Thumbnail
+ ffmpegthumbnailer -i "$FILE_PATH" -o "$IMAGE_CACHE_PATH" -s 0 && exit 6
+ exit 1;;
+ # PDF
+ application/pdf)
+ pdftoppm -f 1 -l 1 \
+ -scale-to-x 1920 \
+ -scale-to-y -1 \
+ -singlefile \
+ -jpeg -tiffcompression jpeg \
+ -- "$FILE_PATH" "$(basename "$IMAGE_CACHE_PATH")" \
+ && exit 6 || exit 1;;
+ esac
+ }
+
+ handle_mime() {
+ local mimetype="$1"
+ case "$mimetype" in
+ # Text
+ text/* | */xml)
+ exit 2;;
+ # Audio
+ audio/*)
+ exiftool "$FILE_PATH" && exit 5
+ exit 1;;
+ esac
+ }
+
+ MIMETYPE="$( file --dereference --brief --mime-type -- "$FILE_PATH" )"
+ if [[ "$PV_IMAGE_ENABLED" == 'True' ]]; then
+ handle_image "$MIMETYPE"
+ fi
+ handle_extension
+ handle_mime "$MIMETYPE"
+ handle_fallback
+ exit 1
+ '';
+
+ # Ranger's bookmarks
+ rangerBookmarks = ''
+ # Local files
+ k:/home/jimbo/Downloads
+ v:/home/jimbo/Videos
+ c:/home/jimbo/.config
+ L:/home/jimbo/.local
+ D:/mnt
+ n:/etc/nixos
+
+ # Remote files
+ a:/home/jimbo/JimboNFS
+ K:/home/jimbo/JimboNFS/Downloads
+ p:/home/jimbo/JimboNFS/Photos
+ P:/home/jimbo/JimboNFS/Projects
+ V:/home/jimbo/JimboNFS/Videos/Random
+ m:/home/jimbo/JimboNFS/Music
+ L:/home/jimbo/JimboNFS/MineServers
+ s:/home/jimbo/JimboNFS/School
+ N:/home/jimbo/JimboNFS/JimboOS/NixOS
+ '';
+
+ # Sunshine apps config
+ sunshineApps = ''
+ {
+ "env": {
+ "PATH": "$(PATH):$(HOME)\/.local\/bin"
+ },
+ "apps": [{
+ "name": "Desktop",
+ "image-path": "desktop.png"
+ }]
+ }
+ '';
+
+ # ytfzf config
+ ytfzfConf = ''
+ external_menu () {
+ bemenu ${bemenuOpts} -s -l 30 -p "Search"
+ }
+ video_player () {
+ mpv --loop-playlist=no --keep-open=yes "$@"
+ }
+ '';
+
+ # Some sound settings use alsoft, which needs to be configured to use pipewire
+ alsoftConf = ''
+ drivers=pulse
+ '';
+
+ # FireFox/LibreWolf colors
+ foxJimCol = ''
+ :root {
+ --tab-active-bg-color: #${primeCol};
+ --tab-hover-bg-color: #${accentCol};
+ --tab-inactive-bg-color: #${darkCol};
+ --tab-active-fg-fallback-color: #FFFFFF;
+ --tab-inactive-fg-fallback-color: #${textCol};
+ --urlbar-focused-bg-color: #${darkCol};
+ --urlbar-not-focused-bg-color: #${darkCol};
+ --toolbar-bgcolor: #${darkCol} !important;
+ '';
+ foxWorkCol = ''
+ :root {
+ --tab-active-bg-color: #${darkCol};
+ --tab-hover-bg-color: #${accentCol};
+ --tab-inactive-bg-color: #${primeCol};
+ --tab-active-fg-fallback-color: #${textCol};
+ --tab-inactive-fg-fallback-color: #FFFFFF;
+ --urlbar-focused-bg-color: #${primeCol};
+ --urlbar-not-focused-bg-color: #${primeCol};
+ --toolbar-bgcolor: #${primeCol} !important;
+ '';
+ quteFoxCSS = ''
+ --tab-font: '${mainFont}';
+ --urlbar-font: '${mainFont}';
+
+ /* try increasing if you encounter problems */
+ --urlbar-height-setting: 24px;
+ --tab-min-height: 20px !important;
+
+ /* I don't recommend you touch this */
+ --arrowpanel-menuitem-padding: 2px !important;
+ --arrowpanel-border-radius: 0px !important;
+ --arrowpanel-menuitem-border-radius: 0px !important;
+ --toolbarbutton-border-radius: 0px !important;
+ --toolbarbutton-inner-padding: 0px 2px !important;
+ --toolbar-field-focus-background-color: var(--urlbar-focused-bg-color) !important;
+ --toolbar-field-background-color: var(--urlbar-not-focused-bg-color) !important;
+ --toolbar-field-focus-border-color: transparent !important;
+ }
+
+ /* --- General debloat ------------------------------ */
+
+ /* bottom left page loading status or url preview */
+ #statuspanel { display: none !important; }
+
+ /* remove radius from right-click popup */
+ menupopup, panel { --panel-border-radius: 0px !important; }
+ menu, menuitem, menucaption { border-radius: 0px !important; }
+
+ /* no large buttons in right-click menu */
+ menupopup > #context-navigation { display: none !important; }
+ menupopup > #context-sep-navigation { display: none !important; }
+
+ /* --- Debloat navbar ------------------------------- */
+
+ #back-button { display: none; }
+ #forward-button { display: none; }
+ #reload-button { display: none; }
+ #stop-button { display: none; }
+ #home-button { display: none; }
+ #library-button { display: none; }
+ #fxa-toolbar-menu-button { display: none; }
+ /* empty space before and after the url bar */
+ #customizableui-special-spring1, #customizableui-special-spring2 { display: none; }
+
+ /* --- Style navbar -------------------------------- */
+
+ /* remove padding between toolbar buttons */
+ toolbar .toolbarbutton-1 { padding: 0 0 !important; }
+
+ #urlbar-container {
+ --urlbar-container-height: var(--urlbar-height-setting) !important;
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ font-family: var(--urlbar-font, 'monospace');
+ font-size: 14px;
+ }
+
+ #urlbar {
+ --urlbar-height: var(--urlbar-height-setting) !important;
+ --urlbar-toolbar-height: var(--urlbar-height-setting) !important;
+ min-height: var(--urlbar-height-setting) !important;
+ border-color: var(--lwt-toolbar-field-border-color, hsla(240,5%,5%,.25)) !important;
+ }
+
+ #urlbar-input {
+ margin-left: 0.8em !important;
+ margin-right: 0.4em !important;
+ }
+
+ #navigator-toolbox {
+ border: none !important;
+ }
+
+ /* keep pop-up menus from overlapping with navbar */
+ #widget-overflow { margin: 0 !important; }
+ #appmenu-popup { margin: 0 !important; }
+ #customizationui-widget-panel { margin: 0 !important; }
+ #unified-extensions-panel { margin: 0 !important; }
+
+ /* --- Unified extensions button -------------------- */
+
+ /* make extension icons smaller */
+ #unified-extensions-view {
+ --uei-icon-size: 18px;
+ }
+
+ /* hide bloat */
+ .unified-extensions-item-message-deck,
+ #unified-extensions-view > .panel-header,
+ #unified-extensions-view > toolbarseparator,
+ #unified-extensions-manage-extensions {
+ display: none !important;
+ }
+
+ /* add 3px padding on the top and the bottom of the box */
+ .panel-subview-body {
+ padding: 3px 0px !important;
+ }
+
+ #unified-extensions-view .unified-extensions-item-menu-button {
+ margin-inline-end: 0 !important;
+ }
+
+ #unified-extensions-view .toolbarbutton-icon {
+ padding: 0 !important;
+ }
+
+ .unified-extensions-item-contents {
+ line-height: 1 !important;
+ white-space: nowrap !important;
+ }
+
+ /* --- Debloat URL bar ------------------------------- */
+
+ #identity-box { display: none; }
+ #pageActionButton { display: none; }
+ #pocket-button { display: none; }
+ #urlbar-zoom-button { display: none; }
+ #tracking-protection-icon-container { display: none !important; }
+ #reader-mode-button{ display: none !important; }
+ #star-button { display: none; }
+ #star-button-box:hover { background: inherit !important; }
+
+ /* Go to arrow button at the end of the urlbar when searching */
+ #urlbar-go-button { display: none; }
+
+ /* remove container indicator from urlbar */
+ #userContext-label, #userContext-indicator { display: none !important;}
+
+ /* --- Style tab toolbar ---------------------------- */
+
+ #titlebar {
+ --proton-tab-block-margin: 0px !important;
+ --tab-block-margin: 0px !important;
+ }
+
+ #TabsToolbar, .tabbrowser-tab {
+ max-height: var(--tab-min-height) !important;
+ font-size: 14px !important;
+ }
+
+ /* Change color of normal tabs */
+ tab:not([selected="true"]) {
+ background-color: var(--tab-inactive-bg-color) !important;
+ color: var(--identity-icon-color, var(--tab-inactive-fg-fallback-color)) !important;
+ }
+
+ tab {
+ font-family: var(--tab-font, monospace);
+ border: none !important;
+ }
+
+ /* safari style tab width */
+ .tabbrowser-tab[fadein] {
+ max-width: 100vw !important;
+ border: none
+ }
+
+ /* Hide close button on tabs */
+ #tabbrowser-tabs .tabbrowser-tab .tab-close-button { display: none !important; }
+
+ .tabbrowser-tab {
+ /* remove border between tabs */
+ padding-inline: 0px !important;
+ /* reduce fade effect of tab text */
+ --tab-label-mask-size: 1em !important;
+ /* fix pinned tab behaviour on overflow */
+ overflow-clip-margin: 0px !important;
+ }
+
+ /* Tab: selected colors */
+ #tabbrowser-tabs .tabbrowser-tab[selected] .tab-content {
+ background: var(--tab-active-bg-color) !important;
+ color: var(--identity-icon-color, var(--tab-active-fg-fallback-color)) !important;
+ }
+
+ /* Tab: hovered colors */
+ #tabbrowser-tabs .tabbrowser-tab:hover:not([selected]) .tab-content {
+ background: var(--tab-hover-bg-color) !important;
+ }
+
+ /* hide window controls */
+ .titlebar-buttonbox-container { display: none; }
+
+ /* remove titlebar spacers */
+ .titlebar-spacer { display: none !important; }
+
+ /* disable tab shadow */
+ #tabbrowser-tabs:not([noshadowfortests]) .tab-background:is([selected], [multiselected]) {
+ box-shadow: none !important;
+ }
+
+ /* remove dark space between pinned tab and first non-pinned tab */
+ #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]) >
+ #tabbrowser-arrowscrollbox >
+ .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) {
+ margin-inline-start: 0px !important;
+ }
+
+ /* remove dropdown menu button which displays all tabs on overflow */
+ #alltabs-button { display: none !important }
+
+ /* fix displaying of pinned tabs on overflow */
+ #tabbrowser-tabs:not([secondarytext-unsupported]) .tab-label-container {
+ height: var(--tab-min-height) !important;
+ }
+
+ /* remove overflow scroll buttons */
+ #scrollbutton-up, #scrollbutton-down { display: none !important; }
+
+ /* remove new tab button */
+ #tabs-newtab-button {
+ display: none !important;
+ }
+
+ /* --- Autohide Navbar ------------------------------ */
+
+ /* hide navbar unless focused */
+ #nav-bar {
+ min-height: 0 !important;
+ max-height: 0 !important;
+ height: 0 !important;
+ --moz-transform: scaleY(0) !important;
+ transform: scaleY(0) !important;
+ }
+
+ /* show on focus */
+ #nav-bar:focus-within {
+ --moz-transform: scale(1) !important;
+ transform: scale(1) !important;
+ max-height: var(--urlbar-height-setting) !important;
+ height: var(--urlbar-height-setting) !important;
+ min-height: var(--urlbar-height-setting) !important;
+ }
+
+ #navigator-toolbox:focus-within > .browser-toolbar {
+ transform: translateY(0);
+ opacity: 1;
+ }
+
+ /* --- Hide tab bar on single tab ------------------- */
+
+ #tabbrowser-tabs .tabbrowser-tab:only-of-type,
+ #tabbrowser-tabs .tabbrowser-tab:only-of-type + #tabbrowser-arrowscrollbox-periphery{
+ display:none !important;
+ }
+ #tabbrowser-tabs, #tabbrowser-arrowscrollbox {min-height:0!important;}
+ #alltabs-button {display:none !important;}
+
+ /* --- Prevent tab folding -------------------------- */
+
+ .tabbrowser-tab {
+ min-width: initial !important;
+ }
+ .tab-content {
+ overflow: hidden !important;
+ }
+ '';
+ foxProfiles = ''
+ [Profile0]
+ Name=Jimbo
+ IsRelative=1
+ Path=Jimbo
+ Default=1
+
+ [Profile1]
+ Name=School
+ IsRelative=1
+ Path=School
+
+ [Profile2]
+ Name=Variety
+ IsRelative=1
+ Path=Variety
+
+ [General]
+ StartWithLastProfile=1
+ Version=2
+ '';
+ foxUserJS = ''
+ // Enable Compact Mode
+ user_pref("browser.uidensity", 1);
+
+ // Tracking protection
+ user_pref("browser.contentblocking.category", "strict");
+ user_pref("urlclassifier.trackingSkipURLs", "*.reddit.com, *.twitter.com, *.twimg.com, *.tiktok.com");
+ user_pref("urlclassifier.features.socialtracking.skipURLs", "*.instagram.com, *.twitter.com, *.twimg.com");
+ user_pref("network.cookie.sameSite.noneRequiresSecure", true);
+ user_pref("browser.helperApps.deleteTempFileOnExit", true);
+ user_pref("browser.uitour.enabled", false);
+ user_pref("privacy.globalprivacycontrol.enabled", true);
+ user_pref("privacy.globalprivacycontrol.functionality.enabled", true);
+
+ // Disable Telemetry
+ user_pref("datareporting.policy.dataSubmissionEnabled", false);
+ user_pref("datareporting.healthreport.uploadEnabled", false);
+ user_pref("toolkit.telemetry.unified", false);
+ user_pref("toolkit.telemetry.enabled", false);
+ user_pref("toolkit.telemetry.server", "data:,");
+ user_pref("toolkit.telemetry.archive.enabled", false);
+ user_pref("toolkit.telemetry.newProfilePing.enabled", false);
+ user_pref("toolkit.telemetry.shutdownPingSender.enabled", false);
+ user_pref("toolkit.telemetry.updatePing.enabled", false);
+ user_pref("toolkit.telemetry.bhrPing.enabled", false);
+ user_pref("toolkit.telemetry.firstShutdownPing.enabled", false);
+ user_pref("toolkit.telemetry.coverage.opt-out", true);
+ user_pref("toolkit.coverage.opt-out", true);
+ user_pref("toolkit.coverage.endpoint.base", "");
+ user_pref("browser.ping-centre.telemetry", false);
+ user_pref("browser.newtabpage.activity-stream.feeds.telemetry", false);
+ user_pref("browser.newtabpage.activity-stream.telemetry", false);
+
+ // Disable Experiments
+ user_pref("app.shield.optoutstudies.enabled", false);
+ user_pref("app.normandy.enabled", false);
+ user_pref("app.normandy.api_url", "");
+
+ // Disable Crash Reports
+ user_pref("breakpad.reportURL", "");
+ user_pref("browser.tabs.crashReporting.sendReport", false);
+ user_pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);
+
+ // Detection
+ user_pref("captivedetect.canonicalURL", "");
+ user_pref("network.captive-portal-service.enabled", false);
+ user_pref("network.connectivity-service.enabled", false);
+ '';
+in
+
+{
+ # Define home manager programs and configs
+ home-manager = {
+ useGlobalPkgs = true;
+ useUserPackages = true;
+ users.jimbo = { config, pkgs, ... }: {
+ # Install user programs
+ home.packages = (with pkgs; [
+ # Useful programs
+ rofi-bluetooth bemoji imv qbittorrent libreoffice-fresh
+ easyeffects pavucontrol vesktop ffmpegthumbnailer
+
+ # Terminal programs
+ dua vimv p7zip fastfetch gotop pciutils
+ usbutils tcptrack mpc-cli ncmpcpp
+
+ # Scripts as global programs
+ serverDash beScripts makoToggle swayLock
+ screenShot alarmScript iommuCheck pFetch
+
+ # Production tools
+ krita inkscape audacity blender sunvox
+
+ # File manager
+ pcmanfm-qt gnome.file-roller ranger imagemagick poppler_utils
+
+ # School tools
+ remmina freerdp globalprotect-openconnect python3 zoom-us
+
+ # Audio/Video tools
+ yt-dlp ytfzf spotdl ani-cli playerctl ffmpeg
+
+ # Unlimited games
+ steam steam-run heroic mangohud prismlauncher
+
+ # Emulators
+ #dolphin-emu cemu ryujinx duckstation pcsx2 unstable.lime3ds
+
+ # Remote desktop
+ sunshine #moonlight-qt
+
+ # Window manager apps
+ swaybg wdisplays wl-clipboard clipman bemenu
+ libnotify bc grim slurp swappy jq lm_sensors
+ ]);
+
+ # Enable Sway and write some scripts
+ wayland.windowManager.sway = let
+ # Define certain variables Sway will use
+ primeMod = "Mod4";
+ altMod = "Mod1";
+
+ # Define scripts specific to Sway
+ pinWindow = pkgs.writeScript "pin-window" ''
+ # Get the current border style of the focused window
+ current_style=$(swaymsg -t get_tree | jq -r '.. | select(.focused?).border')
+
+ # Toggle between "normal" (default) and "pixel ${borderWeight}" border styles
+ if [ "$current_style" == "none" ]; then
+ swaymsg "sticky disable, border pixel ${borderWeight}"
+ else
+ swaymsg "sticky enable, border none"
+ fi
+ '';
+
+ # Kill a window or probe it for info
+ swayTools = pkgs.writeScript "swaytools" ''
+ # List the app name and whether or not it uses wayland
+ swayprop() {
+ selected_window=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)"' | slurp -r -c ${primeCol} -B 00000066 -b 00000000)
+ if [ -n "$selected_window" ]; then
+ app_id=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .app_id')
+ system=$(sed 's/xdg_shell/Wayland/g; s/xwayland/Xorg/g' < <(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .shell'))
+ notify-send "$(echo -e "Window's app_id: $app_id\nWindow System: $system")"
+ fi
+ }
+
+ # Kill a selected window
+ swaykill() {
+ selected_window=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)"' | slurp -r -c ${primeCol} -B 00000066 -b 00000000)
+ if [ -n "$selected_window" ]; then
+ pid=$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | select("\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height)" == "'"$selected_window"'") | .pid')
+ kill -9 "$pid"
+ fi
+ }
+
+ # Handle which tool we use
+ if [ "$1" == "--prop" ]; then
+ swayprop
+ elif [ "$1" == "--kill" ]; then
+ swaykill
+ fi
+ '';
+ in {
+ enable = true;
+ package = pkgs.unstable.sway; # swayfx
+ wrapperFeatures.gtk = true;
+ checkConfig = false;
+ config = {
+ modifier = "${primeMod}";
+ startup = [
+ # Lock the screen on start, to allow an autostarted session
+ { command = "swaylock"; }
+
+ # Scratchpads
+ { command = "${terminalClass} gotop -T Gotop gotop"; }
+ { command = "${terminalClass} music -T Music ncmpcpp"; }
+ { command = "pavucontrol"; }
+ { command = "easyeffects"; }
+
+ # Daemons and tray apps
+ { command = "alarms --alarms"; }
+ { command = "wl-paste -t text --watch clipman store -P"; }
+ { command = "wl-copy"; }
+ { command = "mako"; }
+ { command = "sunshine"; }
+ { command = "${pkgs.rot8}/bin/rot8"; }
+
+ # Polkit agent
+ { command = "${pkgs.mate.mate-polkit}/libexec/polkit-mate-authentication-agent-1"; }
+
+ # Foreground apps
+ { command = "librewolf -P Variety --name=Variety"; }
+ { command = "vesktop --ozone-platform-hint=auto"; }
+ { command = "serverdash"; }
+ ];
+
+ # Use Waybar rather than Sway's
+ bars = [{ command = "waybar"; }];
+
+ # Define hardware
+ output = {
+ ${display1} = {
+ pos = "1920 405";
+ mode = "1920x1080@143.980Hz";
+ max_render_time = "3";
+ bg = "${wallpaper1} fill";
+ scale = "1";
+ adaptive_sync = "on";
+ };
+ ${display2} = {
+ pos = "0 405";
+ mode = "1920x1080@60Hz";
+ max_render_time = "3";
+ bg = "${wallpaper2} fill";
+ };
+ ${display3} = {
+ pos = "3840 0";
+ mode = "1680x1050@59.883Hz";
+ transform = "270";
+ max_render_time = "3";
+ bg = "${wallpaper3} fill";
+ };
+ ${displayTouch} = {
+ #scale = "1.4";
+ };
+ "*" = {
+ bg = "${wallpaper1} fill";
+ };
+ };
+
+ # Mouse sensitivity, disable acceleration, allow touch while typing
+ input = {
+ "9610:4103:SINOWEALTH_Game_Mouse" = {
+ pointer_accel = "-0.9";
+ };
+ "9639:64097:Compx_2.4G_Receiver_Mouse" = {
+ pointer_accel = "-0.82";
+ };
+ "1452:627:bcm5974" = {
+ scroll_factor = "0.3";
+ };
+ "*" = {
+ accel_profile = "flat";
+ dwt = "disabled";
+ natural_scroll = "disabled";
+ };
+
+ # Map touchscreen to output
+ "1386:806:Wacom_ISDv5_326_Finger" = {
+ map_to_output = "${displayTouch}";
+ };
+ };
+
+ # Assign workspaces to outputs
+ workspaceOutputAssign = let
+ workspaces1 = [ "${w0}" "${w1}" "${w2}" "${w3}" "${w1a}" "${w2a}" "${w3a}" ];
+ workspaces2 = [ "${w4}" "${w5}" "${w6}" "${w4a}" "${w5a}" "${w6a}" ];
+ workspaces3 = [ "${w7}" "${w8}" "${w9}" "${w7a}" "${w8a}" "${w9a}" ];
+ assign = output: workspaces: map (workspace: { inherit workspace; inherit output; }) workspaces;
+ in
+ (assign "${display1}" workspaces1) ++ (assign "${display2}" workspaces2) ++ (assign "${display3}" workspaces3);
+
+ # Theming settings
+ fonts = {
+ names = [ "${mainFont}" ];
+ size = 10.5;
+ };
+ gaps = {
+ inner = 5;
+ smartGaps = true;
+ };
+ focus = {
+ newWindow = "focus";
+ };
+ colors = {
+ focused = {
+ border = "#${primeCol}";
+ background = "#${primeCol}";
+ text = "#FFFFFF";
+ indicator = "#${actSplitCol}";
+ childBorder = "#${primeCol}";
+ };
+ focusedInactive = {
+ border = "#${accentCol}";
+ background = "#${accentCol}";
+ text = "#${textCol}";
+ indicator = "#${splitCol}";
+ childBorder = "#${accentCol}";
+ };
+ unfocused = {
+ border = "#${darkCol}";
+ background = "#${darkCol}";
+ text = "#${textCol}";
+ indicator = "#${splitCol}";
+ childBorder = "#${splitCol}";
+ };
+ urgent = {
+ border = "#${urgentCol}";
+ background = "#${urgentCol}";
+ text = "#${textCol}";
+ indicator = "#${urgentCol}";
+ childBorder = "#${urgentCol}";
+ };
+ };
+
+ # Hotkeys
+ keybindings = let
+ resizeAmount = ''55'';
+ sendNotif = ''notify-send --expire-time=1500'';
+ in {
+ ## Launcher keys
+
+ # LibreWolf profiles
+ "${primeMod}+F1" = ''exec librewolf -P Jimbo --name=JimBrowser | ${sendNotif} "LibreWolf Main"'';
+ "${primeMod}+F2" = ''exec librewolf -P School --name=SchoolBrowser | ${sendNotif} "LibreWolf School"'';
+ "${primeMod}+F3" = ''exec librewolf -P Variety --name=Variety | ${sendNotif} "LibreWolf Variety"'';
+
+ # Discord
+ "${primeMod}+F4" = ''exec vesktop --ozone-platform-hint=auto | ${sendNotif} "Discord"'';
+
+ # Games
+ "${primeMod}+F5" = ''exec steam | ${sendNotif} "Steam"'';
+ "${primeMod}+F6" = ''exec heroic | ${sendNotif} "Heroic Games"'';
+
+ # Looking glass for VMs
+ "${primeMod}+F7" = ''exec looking-glass-client input:rawMouse=yes | ${sendNotif} "Looking Glass"'';
+
+ # Virtual Machines
+ "${primeMod}+F10" = ''exec virt-manager | ${sendNotif} "Virtual Machines"'';
+
+ # BeMenu scripts
+ "${primeMod}+F11" = ''exec bescripts --scratchpads | ${sendNotif} "Scratchpads"'';
+ "${primeMod}+${altMod}+Ctrl+r" = ''exec bescripts --resolutions'';
+
+ # Open NixOS configuration files
+ "${primeMod}+F12" = ''exec bash -c "${terminal} nvim /etc/nixos/{configuration,jimbo,hardware-configuration}.nix" | ${sendNotif} "Nix Config"'';
+
+ # Terminal, bemenu, clipmenu, media script, power menu, show/hide waybar
+ "${primeMod}+Return" = ''exec ${terminal}'';
+ "${primeMod}+s" = ''exec bemenu-run ${bemenuOpts} -p Command'';
+ "${primeMod}+c" = ''exec clipman pick -t rofi'';
+ "${primeMod}+y" = ''exec bescripts --media'';
+ "${primeMod}+x" = ''exec bescripts --power'';
+ "${primeMod}+b" = ''exec pkill -USR1 waybar'';
+ "${primeMod}+Escape" = ''exec ${swayTools} --kill'';
+
+ # PCManFM, Emoji Picker, Rofi Launcher, Bluetooth, Ranger
+ "${primeMod}+Shift+t" = ''exec pcmanfm-qt'';
+ "${primeMod}+Shift+e" = ''exec BEMOJI_PICKER_CMD="rofi -dmenu -p Emoji" bemoji -n -P 0'';
+ "${primeMod}+Shift+s" = ''exec rofi -show drun -modi drun -drun-display-format {name} -show-icons -disable-history -terminal ${terminal}'';
+ "${primeMod}+Shift+b" = ''exec rofi-bluetooth'';
+ "${primeMod}+Shift+Return" = ''exec ${terminal} ranger'';
+
+ # Swaytools prop, colorpicker
+ "${primeMod}+Ctrl+x" = ''exec ${swayTools} --prop'';
+ "${primeMod}+Ctrl+c" = ''exec ${pkgs.hyprpicker}/bin/hyprpicker -an && ${sendNotif} "Color copied to clipboard"'';
+
+ ## Media keys
+
+ # Volume control
+ "XF86AudioRaiseVolume" = ''exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+'';
+ "XF86AudioLowerVolume" = ''exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-'';
+
+ # MPV volume control
+ "${altMod}+XF86AudioRaiseVolume" = ''exec mpc volume +3'';
+ "${altMod}+XF86AudioLowerVolume" = ''exec mpc volume -3'';
+
+ # Mute, Stop
+ "XF86AudioMute" = ''exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle'';
+ "XF86AudioStop" = ''exec mpc stop'';
+
+ # Play MPD, Firefox, or MPV
+ "XF86AudioPlay" = ''exec playerctl --player=firefox play-pause'';
+ "Ctrl+XF86AudioPlay" = ''exec playerctl --player=mpv play-pause'';
+ "${altMod}+XF86AudioPlay" = ''exec mpc toggle'';
+
+ # Next/Previous
+ "XF86AudioNext" = ''exec playerctl --player=firefox next'';
+ "XF86AudioPrev" = ''exec playerctl --player=firefox previous'';
+ "${altMod}+XF86AudioNext" = ''exec mpc next'';
+ "${altMod}+XF86AudioPrev" = ''exec mpc prev'';
+
+ # Seek
+ "${altMod}+Shift+XF86AudioNext" = ''exec mpc seek +5'';
+ "${altMod}+Shift+XF86AudioPrev" = ''exec mpc seek -5'';
+
+ ## Notification keys
+
+ # Toggle mako
+ "${primeMod}+n" = ''exec makotoggle'';
+ "${primeMod}+Shift+n" = ''exec makoctl restore'';
+ "${primeMod}+Ctrl+n" = ''exec makoctl dismiss -a'';
+
+ ## Miscellaneous keys
+
+ # Screenshots
+ "Print" = ''exec screenshot --swappy'';
+ "${primeMod}+Shift+f" = ''exec screenshot --swappy'';
+ "Shift+Print" = ''exec screenshot --current'';
+ "Ctrl+Print" = ''exec screenshot --all'';
+
+ # Server SSH
+ "${primeMod}+Ctrl+Return" = ''exec ${terminal} ssh server -p 2222'';
+
+ # Display Brightness and Keyboard Brightness
+ "XF86MonBrightnessUp" = ''exec light -A 5'';
+ "XF86MonBrightnessDown" = ''exec light -U 5'';
+ "Shift+XF86MonBrightnessUp" = ''exec light -A 1'';
+ "Shift+XF86MonBrightnessDown" = ''exec light -U 1'';
+ "XF86KbdBrightnessUp" = ''exec light -s sysfs/leds/smc::kbd_backlight -A 5'';
+ "XF86KbdBrightnessDown" = ''exec light -s sysfs/leds/smc::kbd_backlight -U 5'';
+
+ ## Window manager keys
+ "${primeMod}+q" = ''kill'';
+ "${primeMod}+Shift+r" = ''reload'';
+
+ # Switch to workspaces
+ "${primeMod}+grave" = ''workspace ${w0}'';
+ "${primeMod}+1" = ''workspace ${w1}'';
+ "${primeMod}+2" = ''workspace ${w2}'';
+ "${primeMod}+3" = ''workspace ${w3}'';
+ "${primeMod}+4" = ''workspace ${w4}'';
+ "${primeMod}+5" = ''workspace ${w5}'';
+ "${primeMod}+6" = ''workspace ${w6}'';
+ "${primeMod}+7" = ''workspace ${w7}'';
+ "${primeMod}+8" = ''workspace ${w8}'';
+ "${primeMod}+9" = ''workspace ${w9}'';
+
+ # Switch to alternate workspaces
+ "${altMod}+F1" = ''workspace ${w1a}'';
+ "${altMod}+F2" = ''workspace ${w2a}'';
+ "${altMod}+F3" = ''workspace ${w3a}'';
+ "${altMod}+F4" = ''workspace ${w4a}'';
+ "${altMod}+F5" = ''workspace ${w5a}'';
+ "${altMod}+F6" = ''workspace ${w6a}'';
+ "${altMod}+F7" = ''workspace ${w7a}'';
+ "${altMod}+F8" = ''workspace ${w8a}'';
+ "${altMod}+F9" = ''workspace ${w9a}'';
+
+ # Move window to and focus new workspace
+ "${primeMod}+Shift+grave" = ''move container to workspace ${w0}; workspace ${w0}'';
+ "${primeMod}+Shift+1" = ''move container to workspace ${w1}; workspace ${w1}'';
+ "${primeMod}+Shift+2" = ''move container to workspace ${w2}; workspace ${w2}'';
+ "${primeMod}+Shift+3" = ''move container to workspace ${w3}; workspace ${w3}'';
+ "${primeMod}+Shift+4" = ''move container to workspace ${w4}; workspace ${w4}'';
+ "${primeMod}+Shift+5" = ''move container to workspace ${w5}; workspace ${w5}'';
+ "${primeMod}+Shift+6" = ''move container to workspace ${w6}; workspace ${w6}'';
+ "${primeMod}+Shift+7" = ''move container to workspace ${w7}; workspace ${w7}'';
+ "${primeMod}+Shift+8" = ''move container to workspace ${w8}; workspace ${w8}'';
+ "${primeMod}+Shift+9" = ''move container to workspace ${w9}; workspace ${w9}'';
+
+ # Move window to and focus new alternate workspace
+ "${altMod}+Shift+F1" = ''move container to workspace ${w1a}; workspace ${w1a}'';
+ "${altMod}+Shift+F2" = ''move container to workspace ${w2a}; workspace ${w2a}'';
+ "${altMod}+Shift+F3" = ''move container to workspace ${w3a}; workspace ${w3a}'';
+ "${altMod}+Shift+F4" = ''move container to workspace ${w4a}; workspace ${w4a}'';
+ "${altMod}+Shift+F5" = ''move container to workspace ${w5a}; workspace ${w5a}'';
+ "${altMod}+Shift+F6" = ''move container to workspace ${w6a}; workspace ${w6a}'';
+ "${altMod}+Shift+F7" = ''move container to workspace ${w7a}; workspace ${w7a}'';
+ "${altMod}+Shift+F8" = ''move container to workspace ${w8a}; workspace ${w8a}'';
+ "${altMod}+Shift+F9" = ''move container to workspace ${w9a}; workspace ${w9a}'';
+
+ # Change focus across windows
+ "${primeMod}+Up" = ''focus up'';
+ "${primeMod}+Down" = ''focus down'';
+ "${primeMod}+Left" = ''focus left'';
+ "${primeMod}+Right" = ''focus right'';
+
+ # Switch focus across outputs
+ "${primeMod}+j" = ''focus output ${display2}'';
+ "${primeMod}+k" = ''focus output ${display1}'';
+ "${primeMod}+l" = ''focus output ${display3}'';
+
+ # Move focused window
+ "${primeMod}+Shift+Up" = ''move up ${resizeAmount} px'';
+ "${primeMod}+Shift+Down" = ''move down ${resizeAmount} px'';
+ "${primeMod}+Shift+Left" = ''move left ${resizeAmount} px'';
+ "${primeMod}+Shift+Right" = ''move right ${resizeAmount} px'';
+
+ # Move window across outputs
+ "${primeMod}+Shift+j" = ''move output ${display2}; focus output ${display2}'';
+ "${primeMod}+Shift+k" = ''move output ${display1}; focus output ${display1}'';
+ "${primeMod}+Shift+l" = ''move output ${display3}; focus output ${display3}'';
+
+ # Change focus between floating/tiled, toggle floating
+ "${primeMod}+space" = ''focus mode_toggle'';
+ "${primeMod}+Shift+space" = ''floating toggle'';
+
+ # Allow a window to be visible on all workspaces, toggle border
+ "${primeMod}+0" = ''exec ${pinWindow}'';
+
+ # Toggle fullscreen
+ "${primeMod}+f" = ''fullscreen toggle'';
+ "${primeMod}+${altMod}+Ctrl+f" = ''fullscreen toggle global'';
+
+ # Change container layout
+ "${primeMod}+w" = ''layout toggle split'';
+ "${primeMod}+e" = ''layout toggle tabbed stacking'';
+
+ # Change split direction
+ "${primeMod}+h" = ''split h'';
+ "${primeMod}+v" = ''split v'';
+
+ # Focus parent / child
+ "${primeMod}+a" = ''focus parent'';
+ "${primeMod}+d" = ''focus child'';
+
+ # Resize windows
+ "${primeMod}+${altMod}+Up" = ''resize grow height ${resizeAmount} px or 5 ppt'';
+ "${primeMod}+${altMod}+Down" = ''resize shrink height ${resizeAmount} px or 5 ppt'';
+ "${primeMod}+${altMod}+Left" = ''resize shrink width ${resizeAmount} px or 5 ppt'';
+ "${primeMod}+${altMod}+Right" = ''resize grow width ${resizeAmount} px or 5 ppt'';
+
+ # Adjust gap size
+ "${primeMod}+Shift+equal" = ''gaps inner current set 5'';
+ "${primeMod}+equal" = ''gaps inner current plus 5'';
+ "${primeMod}+minus" = ''gaps inner current minus 5'';
+
+ # Scratchpads
+ "Ctrl+Shift+Escape" = ''[app_id="gotop"] scratchpad show, move position center, resize set 1216 888'';
+ "${primeMod}+Shift+m" = ''[app_id="music"] scratchpad show, move position center, resize set 1006 657'';
+ "${primeMod}+Shift+v" = ''[app_id="pavucontrol"] scratchpad show, move position center, resize set 1000 800'';
+ "${primeMod}+Shift+Backslash" = ''[app_id="com.github.wwmm.easyeffects"] scratchpad show, move position center, resize set 1000 800'';
+ };
+ window = {
+ border = borderWeightInt;
+ titlebar = false;
+ commands = [
+ # Scratchpads
+ { command = ''floating enable, sticky enable, move scratchpad, mark borderless'';
+ criteria = { con_mark = "scratchpad"; }; }
+ { command = ''mark scratchpad'';
+ criteria = { app_id = "gotop"; }; }
+ { command = ''mark scratchpad'';
+ criteria = { app_id = "music"; }; }
+ { command = ''mark scratchpad, opacity 0.9'';
+ criteria = { app_id = "pavucontrol"; }; }
+ { command = ''mark scratchpad, opacity 0.9'';
+ criteria = { app_id = "com.github.wwmm.easyeffects"; }; }
+
+ # Create a "Scratchpad" for apps I don't want to be seen when launched
+ { command = ''move scratchpad''; criteria = { con_mark = "hiddenaway"; }; }
+
+ # Give apps that don't have them borders
+ { command = ''border pixel ${borderWeight}''; criteria = { con_mark = "borderless"; }; }
+ { command = ''mark borderless''; criteria = { app_id = "com.github.wwmm.easyeffects"; }; }
+ { command = ''mark borderless''; criteria = { class = "steam"; }; }
+ { command = ''mark borderless''; criteria = { app_id = "swappy"; }; }
+ { command = ''mark borderless''; criteria = { app_id = "virt-manager"; }; }
+ { command = ''mark borderless''; criteria = { window_role = "pop-up"; }; }
+
+ # Floating or fullscreen rules
+ { command = ''floating enable''; criteria = { app_id = "smb"; }; }
+ { command = ''floating enable''; criteria = { app_id = "float"; }; }
+ { command = ''floating enable, fullscreen enable global''; criteria = { title = "^GlobalShot"; }; }
+ ];
+ };
+ assigns = {
+ # Browsers
+ "${w1}" = [{ app_id = "JimBrowser"; }];
+ "${w1a}" = [{ app_id = "SchoolBrowser"; }];
+ "${w7}" = [{ app_id = "Variety"; }];
+
+ # Communication
+ "${w3a}" = [{ class = "zoom"; }];
+ "${w8}" = [{ app_id = "vesktop"; }];
+
+ # Else
+ "${w2}" = [{ class = "steam"; } { class = "heroic"; } { app_id = "lutris"; }];
+ "${w2a}" = [{ app_id = "looking-glass-client"; }];
+ "${w4}" = [{ app_id = "serverdash"; }];
+ "${w4a}" = [{ app_id = "com.obsproject.Studio"; }];
+ };
+ };
+ extraConfig = ''
+ # Options I can't find in Nix yet
+ default_floating_border pixel ${borderWeight}
+ hide_edge_borders --i3 smart
+ titlebar_padding 10 1
+ primary_selection disabled
+
+ # SwayFX specific options
+ #blur enable
+ #blur_passes 3
+ #blur_radius 5
+ #layer_effects 'rofi' blur enable
+ #layer_effects 'notifications' blur enable; blur_ignore_transparent enable
+
+ # Include extra window icons
+ include ${pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/iguanajuice/sway-font-awesome/6b7a9d08974eea1b9cddb8d444e1c89d6837083a/icons";
+ sha256 = "09ki5qw1h91kd33k3fwzq7cb6ck8sq4haswgizrsy387sfr2a75x";
+ }}
+
+ # Switch to workspace 1
+ workspace ${w7}
+ workspace ${w1}
+ '';
+ };
+
+ # Define Waybar
+ programs.waybar = let
+ # Sway workspaces
+ swayWorkspacesModule = {
+ format = "{name}";
+ enable-bar-scroll = true;
+ warp-on-scroll = false;
+ disable-scroll-wraparound = true;
+ };
+
+ # Sway windows
+ swayWindowsModule = {
+ icon = true;
+ icon-size = 15;
+ all-outputs = true;
+ tooltip = false;
+ rewrite = {
+ "(.*) — LibreWolf" = " $1";
+ "LibreWolf" = " LibreWolf";
+ "(.*) - YouTube — LibreWolf" = " $1";
+ };
+ };
+
+ # Pipewire/Pulseaudio
+ pulseModule = {
+ format = "{icon} {volume}%";
+ format-bluetooth = "{icon} {volume}%";
+ format-muted = " muted";
+ format-icons = {
+ headphone = " ";
+ headset = " ";
+ default = [ " " " " ];
+ };
+ on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
+ on-click-middle = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 100%";
+ on-click-right = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 60%";
+ ignored-sinks = [ "Easy Effects Sink" "USB FS AUDIO Analog Stereo" ];
+ };
+
+ # CPU, Ram and Vram
+ cpuModule = {
+ format = " {usage}%";
+ interval = 3;
+ };
+ ramModule = {
+ format = " {used}G";
+ tooltip = false;
+ };
+ vramModule = {
+ exec = pkgs.writeScript "vramScript" ''
+ # Don't run the script if running on integrated graphics
+ if lspci -k | grep "Kernel driver in use: nvidia" &> /dev/null || lspci -k | grep "Kernel driver in use: amdgpu" &> /dev/null; then
+
+ # Run the nvidia-smi command and capture the VRAM usage and GPU utilization output
+ if lspci -k | grep "Kernel driver in use: nvidia" &> /dev/null; then
+ vram_usage_mb=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits)
+ temperature=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader,nounits)
+
+ # Check the drm memory if an AMD GPU is present
+ elif lspci -k | grep "Kernel driver in use: amdgpu" &> /dev/null; then
+ vram_usage_mb=$(echo "$(cat /sys/class/drm/card0/device/mem_info_vram_used || cat /sys/class/drm/card1/device/mem_info_vram_used) / 1024 / 1024" | bc)
+ temperature=$(sensors | grep 'edge' | awk '{print $2}' | sed 's/[^0-9.-]//g')
+ fi
+
+ # Check if VRAM usage is under 1GB
+ if [ $vram_usage_mb -lt 1024 ]; then
+ vram_usage_display="$(echo $vram_usage_mb)M"
+ else
+ # Convert MB to GiB
+ vram_usage_gib=$(bc <<< "scale=2; $vram_usage_mb / 1024")
+ vram_usage_display="$(echo $vram_usage_gib)G"
+ fi
+
+ # Print the VRAM usage in MB or GiB, and include GPU utilization and temperature
+ echo "{\"text\":\" $(echo $vram_usage_display)\",\"tooltip\":\"$(echo $temperature)°C\"}"
+ else
+ :
+ fi
+ '';
+ format = "{}";
+ return-type = "json";
+ interval = 3;
+ };
+
+ # Clocks
+ longClockModule = {
+ exec = pkgs.writeScript "longClock" ''
+ # Long clock format, with a numeric date and military time tooltip
+ time=$(date +'%a %b %d %l:%M:%S%p' | tr -s ' ')
+ date=$(date "+%Y-%m-%d")
+ echo "{\"text\":\" $time\",\"tooltip\":\"$date\"}"
+ '';
+ on-click = ''wl-copy $(date "+%Y-%m-%d-%H%M%S"); notify-send "Date copied."'';
+ format = "{}";
+ return-type = "json";
+ interval = 1;
+ tooltip = true;
+ };
+ shortClockModule = {
+ exec = "echo ' '$(date +'%l:%M%p' | sed 's/^ //')";
+ on-click = ''wl-copy $(date "+%Y-%m-%d-%H%M%S"); notify-send "Date copied."'';
+ interval = 60;
+ tooltip = false;
+ };
+
+ # Tray, gamemode, bluetooth, and network tray modules
+ trayModule = {
+ spacing = 5;
+ };
+ networkModule = {
+ format-ethernet = "";
+ format-wifi = "";
+ format-disconnected = "";
+ format-linked = "";
+ tooltip-format-ethernet = "{ipaddr}\n{ifname} ";
+ tooltip-format-wifi = "{ipaddr}\n{essid} ({signalStrength}%)";
+ tooltip-format-disconnected = "Disconnected";
+ };
+ bluetoothModule = {
+ format = "";
+ format-disabled = "";
+ format-no-controller = "";
+ tooltip-format-on = "No devices connected.";
+ tooltip-format-connected = "{num_connections} connected\n{device_enumerate}";
+ tooltip-format-enumerate-connected = "{device_alias}";
+ tooltip-format-enumerate-connected-battery = "{device_alias} {device_battery_percentage}%";
+ on-click = "rofi-bluetooth";
+ };
+ scratchpadModule = {
+ format = " {count}";
+ show-empty = false;
+ tooltip = true;
+ tooltip-format = "{title}";
+ };
+ gamemodeModule = {
+ format = "{glyph}";
+ glyph = "";
+ hide-not-running = true;
+ use-icon = true;
+ icon-spacing = 3;
+ icon-size = 19;
+ tooltip = true;
+ tooltip-format = "Gamemode On";
+ };
+
+ # Special per-bar modules
+ mediaModule = {
+ exec-if = "mpc status | grep -q '^\\[playing\\] \\|^\\[paused\\]'";
+ exec = pkgs.writeScript "mpvMetadata" ''
+ get_metadata() {
+ mpc --format "%file%" | head -n 1 | sed -E 's/\.(mp3|mp4|m4a|mov|flac|opus|oga)$//; s/&/&/g'
+ }
+
+ truncate_string() {
+ local str="$1"
+ local max_length=30
+ if [ $(expr length "$str") -gt $max_length ]; then
+ str=$(expr substr "$str" 1 $max_length)...
+ fi
+ echo "$str"
+ }
+
+ if mpc status 2>/dev/null | grep -q playing; then
+ song_name=$(get_metadata | awk -F ' - ' '{print $2}')
+ if [ -z "$song_name" ]; then
+ song_name=$(get_metadata)
+ fi
+ echo "{\"text\":\"$(truncate_string " $song_name")\",\"tooltip\":\"$(get_metadata)\"}"
+ elif mpc status 2>/dev/null | grep -q paused; then
+ artist_name=$(get_metadata | awk -F ' - ' '{print $1}')
+ if [ -z "$artist_name" ]; then
+ artist_name=$(get_metadata)
+ fi
+ echo "{\"text\":\"$(truncate_string " $artist_name")\",\"tooltip\":\"$(get_metadata)\",\"class\":\"paused\"}"
+ fi
+ '';
+ format = "{}";
+ return-type = "json";
+ interval = 2;
+ max-length = 30;
+ on-click = "mpc toggle";
+ };
+ notificationModule = {
+ exec = pkgs.writeScript "notificationScript" ''
+ # Run makoctl mode and store the output in a variable
+ mode_output=$(makoctl mode)
+
+ # Extract the second line after "default"
+ mode_line=$(echo "$mode_output" | sed -n '/default/{n;p}')
+
+ # Print the notification status with the tooltip
+ if [[ "$mode_line" == "do-not-disturb" ]]; then
+ printf '{"text":" Off","class":"disabled","tooltip":"Notifications Disabled."}'
+ else
+ printf '{"text":" On","tooltip":"Notifications Enabled."}';
+ fi
+ '';
+ format = "{}";
+ return-type = "json";
+ interval = 2;
+ on-click = "makotoggle";
+ };
+ weatherModule = {
+ exec = pkgs.writeScript "weatherScript" ''
+ # Define variables
+ CITY="Maple"
+ API_KEY="18be8db3528f08c33ed9f95698335ea7"
+
+ # Fetch weather data
+ weather_data=$(curl -s "http://api.openweathermap.org/data/2.5/weather?q=$CITY&appid=$API_KEY")
+ weather_condition=$(echo $weather_data | jq -r '.weather[0].main')
+
+ # Map weather conditions to emojis
+ case "$weather_condition" in
+ "Clear") emoji="☀️";;
+ "Clouds") emoji="☁️";;
+ "Rain") emoji="🌧️";;
+ "Drizzle") emoji="🌦️";;
+ "Thunderstorm") emoji="⛈️";;
+ "Snow") emoji="❄️";;
+ "Mist"|"Fog"|"Haze") emoji="🌫️";;
+ *) emoji="🌍";; # Default emoji for unknown
+ esac
+
+ # Extract and format temperature in Celsius
+ temperature_kelvin=$(echo $weather_data | jq -r '.main.temp')
+ temperature_celsius=$(echo "$temperature_kelvin - 273.15" | bc)
+ formatted_temperature=$(printf "%.0f" $temperature_celsius)
+
+ # Display weather emoji and temperature
+ echo {\"text\":\"$emoji $formatted_temperature°C\",\"tooltip\":\"Weather in $CITY: $weather_condition\"}
+ '';
+ format = "{}";
+ return-type = "json";
+ on-click = "xdg-open https://openweathermap.org/city/6173577 | notify-send 'Opening weather'";
+ interval = 150;
+ };
+
+ # Laptop modules
+ backlightModule = {
+ format = "{icon} {percent}%";
+ format-icons = ["" ""];
+ tooltip = false;
+ };
+ batteryModule = {
+ interval = 60;
+ states = {
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-icons = ["" "" "" "" ""];
+ };
+ in {
+ enable = true;
+ settings = {
+ display1 = {
+ name = "bar1";
+ position = "top";
+ layer = "bottom";
+ output = [ display1 "VGA-1" ];
+ modules-left = [ "sway/workspaces" "sway/window" ];
+ modules-right = [
+ "pulseaudio" "cpu" "memory" "custom/vram" "custom/clock-long"
+ "gamemode" "sway/scratchpad" "tray" "bluetooth" "network"
+ ];
+ "sway/workspaces" = swayWorkspacesModule;
+ "sway/window" = swayWindowsModule;
+ "pulseaudio" = pulseModule;
+ "cpu" = cpuModule;
+ "memory" = ramModule;
+ "custom/vram" = vramModule;
+ "custom/clock-long" = longClockModule;
+ "gamemode" = gamemodeModule;
+ "sway/scratchpad" = scratchpadModule;
+ "tray" = trayModule;
+ "bluetooth" = bluetoothModule;
+ "network" = networkModule // { interface = "enp*"; };
+ };
+ display2 = {
+ name = "bar2";
+ position = "top";
+ layer = "bottom";
+ output = [ display2 ];
+ modules-left = [ "sway/workspaces" "sway/window" ];
+ modules-right = [
+ "pulseaudio" "custom/media" "custom/notifs" "cpu"
+ "memory" "custom/vram" "custom/clock-long"
+ ];
+ "sway/workspaces" = swayWorkspacesModule;
+ "sway/window" = swayWindowsModule;
+ "pulseaudio" = pulseModule;
+ "custom/media" = mediaModule;
+ "custom/notifs" = notificationModule;
+ "cpu" = cpuModule;
+ "memory" = ramModule;
+ "custom/vram" = vramModule;
+ "custom/clock-long" = longClockModule;
+ };
+ display3 = {
+ name = "bar3";
+ position = "top";
+ layer = "bottom";
+ output = [ display3 ];
+ modules-left = [ "sway/workspaces" "sway/window" ];
+ modules-right = [
+ "pulseaudio" "custom/weather" "cpu" "memory" "custom/vram" "custom/clock-short"
+ ];
+ "sway/workspaces" = swayWorkspacesModule;
+ "sway/window" = swayWindowsModule;
+ "pulseaudio" = pulseModule;
+ "custom/weather" = weatherModule;
+ "cpu" = cpuModule;
+ "memory" = ramModule;
+ "custom/vram" = vramModule;
+ "custom/clock-short" = shortClockModule;
+ };
+ displayLap = {
+ name = "laptop";
+ position = "top";
+ layer = "bottom";
+ output = [ "eDP-1" "LVDS-1" "DSI-1" "HDMI-A-1" ];
+ modules-left = [ "sway/workspaces" "sway/window" ];
+ modules-right = [
+ "pulseaudio" "custom/media" "custom/notifs" "custom/weather2" "cpu" "memory" "custom/vram" "backlight"
+ "battery" "custom/clock-long" "gamemode" "sway/scratchpad" "tray" "bluetooth" "network"
+ ];
+ "sway/workspaces" = swayWorkspacesModule;
+ "sway/window" = swayWindowsModule;
+ "pulseaudio" = pulseModule;
+ "custom/media" = mediaModule;
+ "custom/notifs" = notificationModule;
+ "custom/weather2" = weatherModule;
+ "cpu" = cpuModule;
+ "memory" = ramModule;
+ "custom/vram" = vramModule;
+ "backlight" = backlightModule;
+ "battery" = batteryModule;
+ "custom/clock-long" = longClockModule;
+ "sway/scratchpad" = scratchpadModule;
+ "tray" = trayModule;
+ "bluetooth" = bluetoothModule;
+ "network" = networkModule;
+ };
+ };
+ style = ''
+ * {
+ border: 0;
+ border-radius: 0;
+ min-height: 0;
+ font-family: ${mainFont}, ${nerdFont};
+ font-size: 15.5px;
+ color: #${textCol};
+ }
+ #waybar {
+ background: #${darkCol};
+ }
+ #workspaces {
+ padding: 0 6px 0 0;
+ }
+ #tray {
+ padding: 0 2px 0 5px;
+ }
+ #network {
+ padding: 0 10px 0 4px;
+ }
+ #network.disconnected,#bluetooth.off {
+ color: #424242;
+ }
+ #bluetooth {
+ margin: 0 6px 0 4px;
+ font-size: 13.4px;
+ }
+ #workspaces button {
+ padding: 0 3px;
+ color: white;
+ border-bottom: 3px solid transparent;
+ min-width: 20px;
+ }
+ #workspaces button.visible {
+ border-bottom: 3px solid #${primeCol};
+ background: #${midCol};
+ }
+ #workspaces button.urgent {
+ border-bottom: 3px solid #${urgentCol};
+ }
+ #workspaces button:hover {
+ box-shadow: none;
+ background: #${lightCol};
+ }
+ #scratchpad {
+ margin-left: 2px;
+ }
+ #cpu {
+ border-bottom: 3px solid #f90000;
+ margin: 0 5px 0 2px;
+ }
+ #memory {
+ border-bottom: 3px solid #4bffdc;
+ margin: 0 5px 0 2px;
+ }
+ #custom-vram {
+ border-bottom: 3px solid #33FF00;
+ margin: 0 5px 0 2px;
+ }
+ #custom-media {
+ border-bottom: 3px solid #ffb066;
+ margin: 0 5px 0 2px;
+ }
+ #custom-clock-long {
+ border-bottom: 3px solid #0a6cf5;
+ margin: 0 5px 0 2px;
+ }
+ #custom-clock-short {
+ border-bottom: 3px solid #0a6cf5;
+ margin: 0 5px 0 2px;
+ }
+ #backlight {
+ border-bottom: 3px solid #5ffca3;
+ margin: 0 5px 0 2px;
+ }
+ #battery {
+ border-bottom: 3px solid #fcfc16;
+ margin: 0 5px 0 2px;
+ }
+ #custom-media.paused {
+ color: #888;
+ }
+ #custom-weather {
+ border-bottom: 3px solid #${primeCol};
+ margin: 0 5px 0 2px;
+ }
+ #custom-weather2 {
+ border-bottom: 3px solid #c75bd3;
+ margin: 0 5px 0 2px;
+ }
+ #custom-notifs {
+ border-bottom: 3px solid #${primeCol};
+ margin: 0 5px 0 2px;
+ }
+ #custom-notifs.disabled {
+ color: #888;
+ }
+ #pulseaudio {
+ margin-right: 5px;
+ }
+ #pulseaudio.muted {
+ color: #424242;
+ }
+ '';
+ };
+
+ # Define GTK theme settings
+ gtk = {
+ enable = true;
+ font = {
+ name = "${mainFont}";
+ size = 11;
+ };
+ theme = themeSettings;
+ iconTheme = {
+ package = pkgs.papirus-icon-theme.override { color = "${folderCol}"; };
+ name = "Papirus-Dark";
+ };
+ cursorTheme = {
+ package = pkgs.simp1e-cursors;
+ name = "Simp1e-Dark";
+ };
+
+ # GTK app bookmarks
+ gtk3.bookmarks = [
+ # Local
+ "file:///home/jimbo/Downloads"
+ "file:///home/jimbo/Documents"
+ "file:///home/jimbo/Videos"
+ "file:///home/jimbo/Pictures/Screenshots"
+
+ # Remote
+ "file:///home/jimbo/JimboNFS/Downloads"
+ "file:///home/jimbo/JimboNFS/Documents"
+ "file:///home/jimbo/JimboNFS/Music"
+ "file:///home/jimbo/JimboNFS/Photos"
+ "file:///home/jimbo/JimboNFS/Videos"
+ "file:///home/jimbo/JimboNFS/MineServers"
+ "file:///home/jimbo/JimboNFS/Projects"
+
+ # Links and mounts
+ "file:///home/jimbo/VMs"
+
+ # More important stuff
+ "file:///home/jimbo/JimboNFS/JimboOS"
+ "file:///home/jimbo/JimboNFS/School"
+ ];
+
+ # Stop gtk4 from being rounded
+ gtk4.extraCss = ''
+ window {
+ border-top-left-radius:0;
+ border-top-right-radius:0;
+ border-bottom-left-radius:0;
+ border-bottom-right-radius:0;
+ }
+ '';
+ };
+
+ # Select default apps
+ xdg.mimeApps.defaultApplications = {
+ "inode/directory" = "pcmanfm-qt.desktop";
+ "text/plain" = "nvim.desktop";
+ "image/png" = "imv.desktop";
+ "image/jpeg" = "imv.desktop";
+ };
+
+ # Set dconf settings
+ dconf.settings = {
+ "org/gnome/desktop/interface/color-scheme" = {
+ color-scheme = "prefer-dark";
+ };
+ "org/virt-manager/virt-manager/connections" = {
+ autoconnect = [ "qemu:///system" ];
+ uris = [ "qemu:///system" ];
+ };
+ };
+
+ # Install LibreWolf with settings
+ programs.librewolf = {
+ enable = true;
+ package = pkgs.librewolf;
+ settings = {
+ "general.autoScroll" = true;
+ "browser.compactmode.show" = true;
+ "privacy.clearOnShutdown.history" = false;
+ "privacy.clearOnShutdown.cookies" = false;
+ "network.cookie.lifetimePolicy" = 0;
+ "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+ "browser.toolbars.bookmarks.visibility" = "newtab";
+ "gnomeTheme.hideSingleTab" = true;
+ "svg.context-properties.content.enabled" = true;
+ "media.hardware-video-decoding.force-enabled" = true;
+ "toolkit.tabbox.switchByScrolling" = true;
+ "device.sensors.motion.enabled" = false;
+ #"webgl.disabled" = false;
+ };
+ };
+
+ # Install Neovim and plugins
+ programs.neovim = {
+ enable = true;
+ defaultEditor = true;
+ viAlias = true;
+ vimAlias = true;
+ plugins = with pkgs.vimPlugins; [
+ # Vim theme
+ vim-airline vim-airline-themes
+
+ # Internal clipboard
+ vim-vsnip cmp-vsnip
+
+ # Autocomplete manager
+ lspkind-nvim
+
+ # Autocomplete plugins
+ cmp-nvim-lsp cmp-buffer cmp-path cmp-cmdline nvim-cmp
+
+ # Hex color visualizer and color theme
+ nvim-colorizer-lua vim-monokai-pro
+ ];
+ extraConfig = ''
+ lua <'] = cmp.mapping.scroll_docs(-4),
+ [''] = cmp.mapping.scroll_docs(4),
+ [''] = cmp.mapping.complete(),
+ [''] = cmp.mapping.abort(),
+ [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
+ }),
+ sources = cmp.config.sources({
+ { name = 'nvim_lsp' },
+ { name = 'vsnip' }
+ }, {
+ { name = 'buffer' },
+ })
+ })
+
+ -- Use buffer source for '/' and '?'
+ cmp.setup.cmdline({ '/', '?' }, {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = {
+ { name = 'buffer' }
+ }
+ })
+
+ -- Use cmdline & path source for ':'
+ cmp.setup.cmdline(':', {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = cmp.config.sources({
+ { name = 'path' }
+ }, {
+ { name = 'cmdline' }
+ })
+ })
+ EOF
+
+ colorscheme monokai_pro
+ let g:airline_theme='onedark'
+ let g:airline#extensions#tabline#enabled = 1
+ hi Normal guibg=none ctermbg=235
+ hi Visual guibg=#${midCol} ctermbg=238
+ hi Pmenu guibg=#${midCol} ctermbg=238
+ hi EndOfBuffer guibg=none ctermbg=235
+ hi LineNr guibg=none ctermbg=none
+ lua require'colorizer'.setup()
+
+ set nu rnu
+ set termguicolors
+ set mouse=a
+
+ set undofile
+ set undodir=$HOME/.local/share/nvim/undo
+ set undolevels=100
+ set undoreload=10000
+
+ nmap :bnext
+ nmap :bprev
+ nmap :bd
+ '';
+ };
+
+ # Enable tmux
+ programs.tmux = {
+ enable = true;
+ extraConfig = ''
+ set -g mouse on
+ set -g base-index 1
+ set -g default-terminal "st-256color"
+ set -g history-limit 4096
+ set -g set-titles on
+ set -g set-titles-string "#T"
+ set -g status on
+ set -g status-left ""
+ set -g status-position bottom
+ set -g status-right "#[bg=brightblack]#[fg=dark_purple] #T "
+ set -g status-style "bg=black"
+ setw -g pane-base-index 1
+ setw -g window-status-format "#[bg=brightmagenta]#[fg=black] #I #[bg=brightblack]#[fg=white] #W "
+ setw -g window-status-current-format "#[bg=brightmagenta]#[fg=black] #I #[bg=white]#[fg=black] #W "
+ '';
+ };
+
+ # Enable Rofi
+ programs.rofi = {
+ enable = true;
+ package = pkgs.rofi-wayland;
+ font = "${mainFont} 14";
+ theme = let
+ inherit (config.lib.formats.rasi) mkLiteral;
+ in {
+ "*" = {
+ lightbg = mkLiteral "#EEE8D5";
+ lightfg = mkLiteral "#586875";
+ blue = mkLiteral "#268BD2";
+ red = mkLiteral "#DC322F";
+ background-color = mkLiteral "#00000000";
+ separatorcolor = mkLiteral "#00000000";
+ normal-foreground = mkLiteral "#${textCol}";
+ normal-background = mkLiteral "#${darkCol}1A";
+ urgent-foreground = mkLiteral "#${urgentCol}";
+ active-foreground = mkLiteral "#${splitCol}";
+ selected-active-foreground = mkLiteral "#${primeCol}";
+ background = mkLiteral "#${darkCol}B3";
+ bordercolor = mkLiteral "#${primeCol}";
+ selected-normal-foreground = mkLiteral "#FFFFFF";
+ selected-normal-background = mkLiteral "#${primeCol}80";
+ border-color = mkLiteral "#${primeCol}";
+ urgent-background = mkLiteral "#${accentCol}26";
+ active-background = mkLiteral "#${accentCol}26";
+ selected-active-background = mkLiteral "#${splitCol}54";
+ };
+ "#window" = {
+ background-color = mkLiteral "@background";
+ width = 500;
+ border = mkLiteral "${borderWeight}";
+ padding = 5;
+ };
+ "#message" = {
+ border = mkLiteral "1px dash 0px 0px";
+ border-color = mkLiteral "@separatorcolor";
+ padding = 1;
+ };
+ "#textbox" = {
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#listview" = {
+ fixed-height = 0;
+ border-color = mkLiteral "@separatorcolor";
+ scrollbar = mkLiteral "false";
+ columns = 2;
+ };
+ "#element" = {
+ border = 0;
+ padding = 1;
+ };
+ "#element-text" = {
+ background-color = mkLiteral "inherit";
+ text-color = mkLiteral "inherit";
+ };
+ "#element.normal.normal" = {
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#element.normal.urgent" = {
+ text-color = mkLiteral "@urgent-foreground";
+ };
+ "#element.normal.active" = {
+ background-color = mkLiteral "@active-background";
+ text-color = mkLiteral "@active-foreground";
+ };
+ "#element.selected.normal" = {
+ background-color = mkLiteral "@selected-normal-background";
+ text-color = mkLiteral "@selected-normal-foreground";
+ };
+ "#element.selected.urgent" = {
+ background-color = mkLiteral "@urgent-background";
+ text-color = mkLiteral "@urgent-foreground";
+ };
+ "#element.selected.active" = {
+ background-color = mkLiteral "@selected-active-background";
+ text-color = mkLiteral "@selected-active-foreground";
+ };
+ "#element.alternate.normal" = {
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#element.alternate.urgent" = {
+ text-color = mkLiteral "@urgent-foreground";
+ };
+ "#element.alternate.active" = {
+ background-color = mkLiteral "@active-background";
+ text-color = mkLiteral "@active-foreground";
+ };
+ "#mode-switcher" = {
+ border = mkLiteral "2px dash 0px 0px";
+ border-color = mkLiteral "@separatorcolor";
+ };
+ "#button.selected" = {
+ background-color = mkLiteral "@selected-normal-background";
+ text-color = mkLiteral "@selected-normal-foreground";
+ };
+ "#case-indicator" = {
+ spacing = mkLiteral "0";
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#entry" = {
+ spacing = 0;
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#prompt" = {
+ spacing = 0;
+ text-color = mkLiteral "@normal-foreground";
+ };
+ "#inputbar" = {
+ spacing = 0;
+ text-color = mkLiteral "@normal-foreground";
+ padding = 1;
+ children = map mkLiteral [ "prompt" "textbox-prompt-colon" "entry" ];
+ };
+ "#textbox-prompt-colon" = {
+ expand = false;
+ str = ":";
+ margin = mkLiteral "0px 0.3em 0em 0em";
+ text-color = mkLiteral "@normal-foreground";
+ };
+ };
+ };
+
+ # MPV settings
+ programs.mpv = {
+ enable = true;
+ config = {
+ volume = 55;
+ loop-playlist = "inf";
+ osc = "no";
+ };
+ };
+
+ # Enable Discord Music RPC
+ services.mpd-discord-rpc.enable = true;
+
+ # OBS with plugins
+ programs.obs-studio = {
+ enable = true;
+ plugins = with pkgs.obs-studio-plugins; [
+ obs-pipewire-audio-capture
+ looking-glass-obs
+ obs-webkitgtk
+ advanced-scene-switcher
+ ];
+ };
+
+ # Notification daemon
+ services.mako = {
+ enable = true;
+ borderColor = "#${accentCol}";
+ backgroundColor = "#${darkCol}CC";
+ output = "${display1}";
+ sort = "+time";
+ layer = "overlay";
+ padding = "8";
+ margin = "0";
+ borderSize = borderWeightInt;
+ maxIconSize = 40;
+ defaultTimeout = 6000;
+ font = "${mainFont} 12";
+ anchor = "bottom-right";
+ extraConfig = "on-button-right=dismiss-all\nouter-margin=10\n[mode=do-not-disturb]\ninvisible=1";
+ };
+
+ # Automount with udisk2
+ services.udiskie.enable = true;
+
+ # Start defining arbitrary files
+ home.file = {
+ # Sway scripts
+ ".config/sway/start.sh" = { text = swayStart; executable = true; };
+
+ # Cursor icon theme
+ ".icons/default".source = "${pkgs.simp1e-cursors}/share/icons/Simp1e-Dark";
+
+ # Swappy's config
+ ".config/swappy/config".text = swappyConfig;
+
+ # Foot config file
+ ".config/foot/foot.ini".text = footConf;
+
+ # Easyeffects profile
+ ".config/easyeffects/output/JimHeadphones.json".text = easyEffectsProfile;
+
+ # Mangohud config
+ ".config/MangoHud/MangoHud.conf".text = mangoConf;
+
+ # Fastfetch config
+ ".config/fastfetch/config.jsonc".text = neoConf;
+
+ # PCManFM config
+ ".config/pcmanfm-qt/default/settings.conf".text = pcmanConf;
+
+ # Ranger config
+ ".config/ranger/rc.conf".text = rangerConf;
+ ".config/ranger/rifle.conf".text = rifleConf;
+ ".config/ranger/scope.sh" = { text = rangerScope; executable = true; };
+ ".local/share/ranger/bookmarks".text = rangerBookmarks;
+ ".config/ranger/plugins/devicons/devicons.py".source = "${pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/alexanderjeurissen/ranger_devicons/2c3c19dffb4238d01c74515c9eed5088066db243/devicons.py";
+ sha256 = "0girsranwhsgc6kcyh1mkwymx0bl14a2k5nzk3kyllb6ic48c33k";
+ }}";
+ ".config/ranger/plugins/devicons/__init__.py".source = "${pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/alexanderjeurissen/ranger_devicons/2c3c19dffb4238d01c74515c9eed5088066db243/__init__.py";
+ sha256 = "1r086apw20ryxylqgnbynx7mzz779v1w0m40wghmmhlzw4x15fmr";
+ }}";
+
+ # Sunshine config
+ ".config/sunshine/apps.json".text = sunshineApps;
+
+ # YTFZF config
+ ".config/ytfzf/conf.sh".text = ytfzfConf;
+
+ # Alsoft config
+ ".alsoftrc".text = alsoftConf;
+
+ # Ncmpcpp config
+ ".config/ncmpcpp/config".text = "browser_sort_mode = \"name\"";
+
+ # LibreWolf profiles and theming
+ ".librewolf/profiles.ini".text = foxProfiles;
+ ".librewolf/Jimbo/chrome/userChrome.css".text = "${foxJimCol}\n${quteFoxCSS}";
+ ".librewolf/Jimbo/user.js".text = foxUserJS;
+ ".librewolf/School/chrome/userChrome.css".text = "${foxWorkCol}\n${quteFoxCSS}";
+ ".librewolf/School/user.js".text = foxUserJS;
+ ".librewolf/Variety/chrome".source = "${fetchTarball {
+ url = "https://github.com/rafaelmardojai/firefox-gnome-theme/archive/refs/tags/v120.zip";
+ sha256 = "05ndzlhvw0zxxqgc9lp9w6kr764zbh5zv4aw2nk9qfyhr8j3c708";
+ }}";
+ ".librewolf/Variety/user.js".text = foxUserJS;
+
+ # LibreWolf extension symlinks
+ ".librewolf/School/extensions".source =
+ config.lib.file.mkOutOfStoreSymlink "/home/jimbo/.librewolf/Jimbo/extensions";
+ ".librewolf/School/browser-extension-data".source =
+ config.lib.file.mkOutOfStoreSymlink "/home/jimbo/.librewolf/Jimbo/browser-extension-data";
+ ".librewolf/Variety/extensions".source =
+ config.lib.file.mkOutOfStoreSymlink "/home/jimbo/.librewolf/Jimbo/extensions";
+ ".librewolf/Variety/browser-extension-data".source =
+ config.lib.file.mkOutOfStoreSymlink "/home/jimbo/.librewolf/Jimbo/browser-extension-data";
+
+ # Outer Symlinks
+ "VMs".source = config.lib.file.mkOutOfStoreSymlink "/etc/libvirt/VMs";
+ };
+
+ # Define session variables
+ home.sessionVariables = {
+ EDITOR = "nvim";
+ LIBVIRT_DEFAULT_URI = "qemu:///system";
+ HISTCONTROL = "ignoreboth";
+ };
+
+ # Shell aliases
+ programs.zsh = {
+ enable = true;
+ autosuggestion.enable = true;
+ syntaxHighlighting.enable = true;
+ initExtra = ''
+ ${pkgs.any-nix-shell}/bin/any-nix-shell zsh --info-right | source /dev/stdin; pfetch
+ '';
+ oh-my-zsh = {
+ enable = true;
+ plugins = [ "git" ];
+ theme = "agnoster"; # Main PC
+ #theme = "risto"; # Secondary/VM
+ #theme = "half-life"; # Server
+ };
+ shellAliases = {
+ # NixOS aliases
+ nixcfg = "nvim /etc/nixos/{configuration,jimbo,hardware-configuration}.nix";
+ nixswitch = "${auth} nixos-rebuild switch; notify-send 'NixOS switch finished.'";
+ nixdate = "${auth} nixos-rebuild switch --upgrade-all; notify-send 'NixOS update finished.'";
+ nixclean = "${auth} nix-store --gc; nix-collect-garbage -d; notify-send 'NixOS store clean finished.'";
+ nixpurge = "${auth} nix-collect-garbage --delete-old; notify-send 'NixOS generation removed.'";
+ nixoptimize = "${auth} nix store optimise; notify-send 'NixOS store optimization finished.'";
+
+ # Shortcut aliases
+ neo = "clear && fastfetch";
+ ip = "ip -c";
+ ls = "${pkgs.eza}/bin/eza -a --color=always --group-directories-first --icons";
+ nls = "/usr/bin/env ls";
+ cat = "${pkgs.bat}/bin/bat --paging never";
+ copycat = "wl-copy <";
+ sunshinehost = "WAYLAND_DISPLAY=wayland-1 DISPLAY=:1 sunshine -0";
+ alarmlist = "cat ${alarmScript}/bin/alarms";
+ seneca=''ssh jhampton1@matrix.senecapolytechnic.ca'';
+
+ # Curl tools
+ myip = "curl ifconfig.co";
+
+ # Download from sources
+ ytdl = "yt-dlp --embed-thumbnail --embed-metadata --output \"%(title)s.%(ext)s\"";
+ ytmp4 = "ytdl --recode-video mp4";
+ ytm3u = "yt-dlp -gS proto:m3u8";
+ opusdl = "ytdl --recode-video opus";
+ ytopus = "opusdl --format 251";
+ spotdl = "spotdl --m3u --format opus";
+
+ # Flakes
+ buildiso =
+ "nix run github:nix-community/nixos-generators -- -f install-iso -c /etc/nixos/configuration.nix";
+ };
+ };
+
+ # Define current version
+ home.stateVersion = "24.05";
+ };
+ };
+}
diff --git a/README.md b/README.md
index 4c64586..260f480 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
-# NixOS-Config
+### My Nix "dotfiles", organized in the worst way you will ever see.
-My NixOS configuration.
\ No newline at end of file
+Made with love ❤️
+
+![image](./Extras/Screenshots/SecondUnix.png)
diff --git a/Server/configuration.nix b/Server/configuration.nix
new file mode 100644
index 0000000..231bc67
--- /dev/null
+++ b/Server/configuration.nix
@@ -0,0 +1,543 @@
+{ config, pkgs, options, lib, ... }:
+let
+ # Import home manager
+ homeManager = fetchTarball
+ "https://github.com/nix-community/home-manager/archive/release-24.05.tar.gz";
+
+ # Define domains and ips
+ jimdomain = ''jimbosfiles.com'';
+ bloxeldomain = ''bloxelcom.net'';
+
+ # IPs
+ localspan = ''192.168.1'';
+ pc = ''${localspan}.18'';
+ server = ''${localspan}.17'';
+ vm = ''${localspan}.70'';
+in
+
+{
+ # Import other nix files and firmware
+ imports = [
+ ./hardware-configuration.nix
+ ./jimbo.nix
+ "${homeManager}/nixos"
+ ];
+
+ # Allow unfree packages
+ nixpkgs.config.allowUnfree = true;
+
+ # Allow flakes (I have no clue how they work yet)
+ nix.settings.experimental-features = [ "nix-command" "flakes" ];
+
+ # Allow unfree firmware
+ hardware.enableRedistributableFirmware = true;
+
+ # Choose Grub as the bootloader
+ boot = {
+ kernelPackages = pkgs.linuxPackages_xanmod;
+ loader = {
+ grub = {
+ efiSupport = true;
+ device = "nodev";
+ };
+ };
+ };
+
+ # Enable a permissioning system
+ security = {
+ sudo.enable = false;
+ doas = {
+ enable = true;
+ extraRules = [
+ # Give wheel root access, allow persistant session
+ { groups = [ "wheel" ]; keepEnv = true; persist = true; }
+ ];
+ };
+ };
+
+ # Enable the ZSH shell
+ programs.zsh.enable = true;
+
+ # Disable Nano
+ programs.nano.enable = false;
+
+ # Define a user account.
+ users.users.jimbo = {
+ isNormalUser = true;
+ hashedPassword =
+ "$6$gYpE.pG/zPXgin06$2kydjDfd0K62Dhf9P0PFvJhRNz6xIC/bHYaf/XYqyKcLyZNzPQpy8uy9tCRcSYlj1wwBhzVtTRyItwajOHCEj0";
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDLe/HioxCOkszFQdm1vb3ZwuzLzsOThqHNvEI4IXeXZ JimPhone"
+ ];
+ extraGroups = [ "wheel" "docker" ];
+ uid = 1000;
+ shell = pkgs.zsh;
+ };
+
+ # Add Nginx to the Turnserver group
+ users.users.nginx.extraGroups = [ "turnserver" ];
+
+ # Installed programs to the system profile.
+ environment.systemPackages = with pkgs; [
+ # Essential system tools
+ git parted mdadm
+ ];
+
+ # Define timezone and networking settings
+ time.timeZone = "America/New_York";
+ networking = {
+ # Set hostname
+ hostName = "JimNixServer";
+
+ # Choose networking method
+ dhcpcd.enable = true;
+ wireless.enable = false;
+
+ # Enable firewall passthrough
+ firewall = {
+ allowedTCPPorts = [
+ # NFS
+ 2049
+
+ # Nginx
+ 80 443 8448
+
+ # Minecraft
+ 25565 19132
+
+ # Gitea
+ 2299
+
+ # Coturn
+ 3478 5349
+ ];
+ allowedTCPPortRanges = [
+ # Also Azuracast
+ { from = 8100; to = 8150; }
+ ];
+ allowedUDPPorts = [
+ # Minecraft Voicechat and Bedrock
+ 25565 19132
+
+ # Coturn again
+ 3478 5349
+ ];
+ allowedUDPPortRanges = [
+ # Coturn
+ { from = 49000; to = 50000; }
+ ];
+
+ # Extra rules that cannot be done above
+ extraCommands =
+
+ # SSH and game servers from my PC
+ ''
+ iptables -t nat -A PREROUTING -p tcp -m tcp --dport 2211 -m comment --comment "SSH to PC" -j DNAT --to-destination ${pc}
+ iptables -t nat -A PREROUTING -p udp -m udp --match multiport --dports 27005,27015,7777,29000 -m comment --comment "Games" -j DNAT --to-destination ${pc}
+ '' +
+
+ # Sunshine ports for PC and VM
+ ''
+ iptables -t nat -A PREROUTING -p tcp -m tcp --match multiport --dports 48010,47989,47984 -m comment --comment "PC Sunshine TCP" -j DNAT --to-destination ${pc}
+ iptables -t nat -A PREROUTING -p udp -m udp --match multiport --dports 47998,47999,48000 -m comment --comment "PC Sunshine UDP" -j DNAT --to-destination ${pc}
+
+ iptables -t nat -A PREROUTING -p tcp -m tcp --match multiport --dports 38010,37989,37984 -m comment --comment "VM Sunshine TCP" -j DNAT --to-destination ${vm}
+ iptables -t nat -A PREROUTING -p udp -m udp --match multiport --dports 37998,37999,38000 -m comment --comment "VM Sunshine UDP" -j DNAT --to-destination ${vm}
+ '' +
+
+ # Set an IP firewall for RTMP
+ ''
+ iptables -N RTMPCHAIN
+ iptables -A INPUT -p tcp -m tcp --match multiport --dports 1935,1945 -j RTMPCHAIN
+ iptables -A RTMPCHAIN -s ${pc} -j ACCEPT
+ iptables -A RTMPCHAIN -s 71.87.124.226 -j ACCEPT
+ iptables -A RTMPCHAIN -j DROP
+ '' +
+
+ # Finalize forwarding
+ ''
+ iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
+ '';
+
+ # Remove the chain and such
+ extraStopCommands = ''
+ iptables -D INPUT -p tcp -m tcp --match multiport --dports 1935,1945 -j RTMPCHAIN
+ iptables -F RTMPCHAIN
+ iptables -X RTMPCHAIN
+ '';
+
+ # Disallow pinging this server
+ allowPing = false;
+ };
+ nameservers = [
+ "1.1.1.1"
+ "9.9.9.9"
+ ];
+ };
+
+ # Boot with compatibility for IP forwarding
+ boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
+
+ # Enable AppArmor
+ security.apparmor.enable = true;
+
+ # Enable all manner of services
+ services = {
+ # SSH
+ openssh = {
+ enable = true;
+ settings = {
+ LogLevel = "VERBOSE";
+ PermitRootLogin = "no";
+ PrintLastLog = "no";
+ PasswordAuthentication = false;
+ };
+ ports = [ 2222 ];
+ };
+
+ # Login attempt lockout
+ fail2ban = {
+ enable = true;
+ maxretry = 5;
+ ignoreIP = [ "${pc}" "${server}" "${vm}" ];
+ };
+
+ # NFS server
+ nfs.server = {
+ enable = true;
+ exports = ''
+ /export/JimboNFS ${localspan}.0/24(rw,nohide,insecure,no_subtree_check)
+ '';
+ };
+
+ # Nginx reverse proxy
+ nginx = {
+ enable = true;
+ package = (pkgs.nginxMainline.override { modules = [ pkgs.nginxModules.rtmp ]; });
+ recommendedTlsSettings = true;
+ recommendedOptimisation = true;
+ recommendedGzipSettings = true;
+ recommendedProxySettings = true;
+ virtualHosts = {
+ # Nextcloud Proxy
+ "cloud.${jimdomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8080";
+ proxyWebsockets = true;
+ extraConfig = "
+ location /.well-known/carddav {
+ return 301 $scheme://$host/remote.php/dav;
+ }
+
+ location /.well-known/caldav {
+ return 301 $scheme://$host/remote.php/dav;
+ }
+ ";
+ };
+ };
+
+ # Vaultwarden Proxy
+ "warden.${jimdomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8222";
+ proxyWebsockets = true;
+ };
+ };
+
+
+ # Recipes Proxy
+ "recipes.${jimdomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:5030";
+ proxyWebsockets = true;
+ };
+ };
+
+ # Bluemap Proxy
+ "bluemap.${jimdomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:31010";
+ proxyWebsockets = true;
+ };
+ };
+
+ # Gitea Proxy
+ "git.${jimdomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3110";
+ proxyWebsockets = true;
+ };
+ };
+
+ # Matrix Proxy
+ "matrix.${bloxeldomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ listen = [
+ { addr = "[::]"; port = 80; ssl = false; }
+ { addr = "0.0.0.0"; port = 80; ssl = false; }
+ { addr = "[::]"; port = 443; ssl = true; }
+ { addr = "0.0.0.0"; port = 443; ssl = true; }
+ { addr = "[::]"; port = 8448; ssl = true; }
+ { addr = "0.0.0.0"; port = 8448; ssl = true; }
+ ];
+ locations."/_matrix".proxyPass = "http://[::1]:8008";
+ locations."/_synapse".proxyPass = "http://[::1]:8008";
+ locations."/.well-known".proxyPass = "http://[::1]:8008";
+ };
+
+ # Element Proxy
+ "chat.${bloxeldomain}" = {
+ addSSL = true;
+ enableACME = true;
+ root = "${pkgs.element-web}";
+ };
+
+ # Coturn Proxy
+ "turn.${bloxeldomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ listen = [
+ { addr = "[::]"; port = 80; ssl = false; }
+ { addr = "0.0.0.0"; port = 80; ssl = false; }
+ ];
+ locations."/".proxyPass = "http://[::1]:1380";
+ };
+
+ # Radio Proxy
+ "wbxdradio.${bloxeldomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:255";
+ proxyWebsockets = true;
+ };
+ };
+
+ # Streaming proxy
+ "live.${bloxeldomain}" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8060";
+ proxyWebsockets = true;
+ };
+ };
+
+ # Staging Bloxel Proxy
+ "staging.${bloxeldomain}" = {
+ addSSL = true;
+ enableACME = true;
+ root = "/var/www/bloxel-landing-page";
+ locations."/bloxcable/hls" = {
+ extraConfig = ''
+ types {
+ application/vnd.apple.mpegurl m3u8;
+ }
+ '';
+ };
+ };
+ };
+ appendConfig = ''
+ rtmp {
+ server {
+ listen 1945;
+ chunk_size 4096;
+ allow publish all;
+ application BloxelesteCA {
+ record off;
+ live on;
+ deny play all;
+ hls on;
+ hls_path /var/www/bloxel-landing-page/bloxcable/hls;
+ hls_fragment_naming system;
+ hls_fragment 3;
+ hls_playlist_length 40;
+ }
+ }
+ }
+ '';
+ };
+
+ # Nextcloud server
+ nextcloud = {
+ enable = true;
+ package = pkgs.nextcloud29;
+ hostName = "localhost";
+ datadir = "/mnt/nextcloud";
+ https = true;
+ config = {
+ adminuser = "jimbo";
+ adminpassFile = "/mnt/nextcloud/password.txt";
+ };
+ settings = {
+ trusted_proxies = [ "127.0.0.1" ];
+ trusted_domains = [ "cloud.${jimdomain}" ];
+ overwriteprotocol = "https";
+ };
+ };
+
+ # Force Nextcloud to use a different port
+ nginx.virtualHosts."localhost" = {
+ listen = [ { addr = "127.0.0.1"; port = 8080; } ];
+ };
+
+ # Vaultwarden password manager
+ vaultwarden = {
+ enable = true;
+ config = {
+ DOMAIN = "https://warden.${jimdomain}";
+ SIGNUPS_ALLOWED = false;
+ ROCKET_ADDRESS = "127.0.0.1";
+ ROCKET_PORT = 8222;
+ ROCKET_LOG = "critical";
+ };
+ };
+
+ # Recipes
+ tandoor-recipes = {
+ enable = true;
+ port = 5030;
+ };
+
+ # Gitea
+ gitea = {
+ enable = true;
+ settings = {
+ server = {
+ DOMAIN = "git.${jimdomain}";
+ ROOT_URL = "https://git.${jimdomain}:443";
+ HTTP_PORT = 3110;
+ SSH_PORT = 2299;
+ START_SSH_SERVER = true;
+ };
+ service.DISABLE_REGISTRATION = true;
+ };
+ };
+
+ # Owncast
+ owncast = {
+ enable = true;
+ port = 8060;
+ listen = "0.0.0.0";
+ };
+
+ # Coturn for VC
+ coturn = rec {
+ enable = true;
+ no-cli = true;
+ no-tcp-relay = true;
+ min-port = 49000;
+ max-port = 50000;
+ use-auth-secret = true;
+ realm = "turn.${bloxeldomain}";
+ static-auth-secret = "will be world readable for local users :(";
+ cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
+ pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
+ };
+
+ # Synapse for Matrix clients
+ matrix-synapse = with config.services.coturn; {
+ enable = true;
+ settings = {
+ server_name = "matrix.${bloxeldomain}";
+ public_baseurl = "https://matrix.${bloxeldomain}";
+ serve_server_wellknown = true;
+
+ # Set the network config
+ listeners = [{
+ # Client config
+ port = 8008;
+ bind_addresses = [ "::" "0.0.0.0" ];
+ resources = [ { compress = false; names = [ "client" "federation" ]; } ];
+ type = "http";
+ tls = false;
+ x_forwarded = true;
+ }];
+
+ # Set the type of database
+ database.name = "sqlite3";
+
+ # Allow account registration
+ enable_registration = true;
+ registration_requires_token = true;
+
+ # General settings
+ url_preview_enabled = true;
+ max_upload_size = "50M";
+ report_stats = false;
+
+ # Turn settings
+ turn_uris = [ "turn:${realm}:3478?transport=udp" "turn:${realm}:3478?transport=tcp" ];
+ turn_shared_secret = static-auth-secret;
+ turn_user_lifetime = "1h";
+
+ # Ratelimiting
+ burst_count = 15;
+ };
+ };
+
+ # Snowflake proxy for Tor
+ snowflake-proxy.enable = true;
+
+ # Fix a nonbuilding issue
+ logrotate.checkConfig = false;
+ };
+
+ # Make Nginx not shit itself
+ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www/bloxel-landing-page/bloxcable/hls/" ];
+
+ # Get certificates for Coturn
+ security.acme = {
+ acceptTerms = true;
+ defaults.email = "jimjam4real@gmail.com";
+ certs = {
+ ${config.services.coturn.realm} = {
+ group = "turnserver";
+ postRun = "systemctl restart coturn.service";
+ };
+ };
+ };
+
+ # Configure the Element web server
+ nixpkgs.config.element-web.conf = {
+ default_server_config = {
+ "m.homeserver" = {
+ base_url = "https://matrix.${bloxeldomain}:443";
+ server_name = "matrix.${bloxeldomain}";
+ };
+ };
+ branding = {
+ welcome_background_url = "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/6658b953-7c85-4d44-9d97-d10a52d54af1/dhqaf1r-5402b859-340f-44cb-bfc6-eef5d541ae7d.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzY2NThiOTUzLTdjODUtNGQ0NC05ZDk3LWQxMGE1MmQ1NGFmMVwvZGhxYWYxci01NDAyYjg1OS0zNDBmLTQ0Y2ItYmZjNi1lZWY1ZDU0MWFlN2QucG5nIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.jqJL7Sx9JHu4RqiQnKKfxoxXD55ZLgzH4liMXxH6LkM";
+ auth_header_logo_url = "https://www.${bloxeldomain}/bloxelcom.png";
+ };
+ embedded_pages = {
+ home_url = "https://www.${bloxeldomain}/";
+ };
+ disable_custom_urls = true;
+ disable_guests = true;
+ default_theme = "dark";
+ };
+
+ # Enable Docker
+ virtualisation.docker = {
+ enable = true;
+ daemon.settings = {
+ log-driver = "json-file";
+ };
+ };
+
+ # Determine the release version and allow auto-upgrades
+ system.stateVersion = "23.11";
+ system.autoUpgrade.enable = false;
+}
diff --git a/Server/hardware-configuration.nix b/Server/hardware-configuration.nix
new file mode 100644
index 0000000..33dc9f2
--- /dev/null
+++ b/Server/hardware-configuration.nix
@@ -0,0 +1,78 @@
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+ imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
+
+ boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "nvme" "usbhid" "sd_mod" "sr_mod" ];
+ boot.kernelModules = [ "kvm-intel" ];
+
+ # Mounting options
+ fileSystems = {
+ "/" = {
+ device = "/dev/disk/by-uuid/8f81cab7-9381-4950-b77f-b85c5fdbad16";
+ fsType = "ext4";
+ };
+ "/boot" = {
+ device = "/dev/disk/by-uuid/2034-754A";
+ fsType = "vfat";
+ };
+ "/home/jimbo/JimboNFS" = {
+ device = "/dev/disk/by-uuid/713fcd92-534c-4153-8e04-e0c6fe5f6a51";
+ fsType = "ext4";
+ neededForBoot = true;
+ };
+ "/export/JimboNFS" = {
+ device = "/home/jimbo/JimboNFS";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/mnt/nextcloud/data/JimboNFS" = {
+ device = "/home/jimbo/JimboNFS";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/var/lib/docker/volumes/azuracast_station_data/_data/bloxradio/media/Music" = {
+ device = "/home/jimbo/JimboNFS/Music";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+
+ # Atrocity
+ "/var/lib/bitwarden_rs" = {
+ device = "/home/jimbo/JimboNFS/System/var/lib/bitwarden_rs";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/var/lib/gitea" = {
+ device = "/home/jimbo/JimboNFS/System/var/lib/gitea";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/var/lib/matrix-synapse" = {
+ device = "/home/jimbo/JimboNFS/System/var/lib/matrix-synapse";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/var/lib/nextcloud" = {
+ device = "/home/jimbo/JimboNFS/System/var/lib/nextcloud";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ "/var/lib/owncast" = {
+ device = "/home/jimbo/JimboNFS/System/var/lib/owncast";
+ fsType = "none";
+ options = [ "bind" ];
+ };
+ };
+ swapDevices = [
+ { device = "/dev/disk/by-uuid/ec422cad-bf93-4b15-b989-2c807f1073a4"; }
+ ];
+
+ # Enables DHCP on each ethernet and wireless interface.
+ networking.useDHCP = lib.mkDefault true;
+
+ # Hardware settings
+ nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+ hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+ boot.swraid.enable = true;
+}
diff --git a/Server/jimbo.nix b/Server/jimbo.nix
new file mode 100644
index 0000000..01daf39
--- /dev/null
+++ b/Server/jimbo.nix
@@ -0,0 +1,559 @@
+{ config, pkgs, options, ... }:
+let
+ # Terminal authenticator
+ auth = ''doas'';
+
+ # Neofetch main config
+ neoConf = ''
+ {
+ "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+ "logo": {
+ "source": "xenia",
+ "color": {
+ "1": "1;97",
+ "2": "red",
+ "3": "yellow"
+ }
+ },
+ "display": {
+ "separator": " \u001b[33m ",
+ "color": "red"
+ },
+ "modules": [
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "host",
+ "format": "{5} {2}",
+ "key": " "
+ },
+ {
+ "type": "cpu",
+ "key": " "
+ },
+ {
+ "type": "gpu",
+ "key": " "
+ },
+ {
+ "type": "disk",
+ "folders": "/",
+ "key": " "
+ },
+ {
+ "type": "memory",
+ "format": "{/1}{-}{/}{/2}{-}{/}{} / {}",
+ "key": " "
+ },
+ {
+ "type": "display",
+ "compactType": "original",
+ "key": " "
+ },
+
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "os",
+ "format": "{3} {12}",
+ "key": " "
+ },
+ {
+ "type": "kernel",
+ "format": "{1} {2}",
+ "key": " "
+ },
+ {
+ "type": "wm",
+ "key": " "
+ },
+ {
+ "type": "shell",
+ "key": " "
+ },
+ {
+ "type": "terminal",
+ "key": " "
+ },
+ {
+ "type": "packages",
+ "key": " "
+ },
+ {
+ "type": "uptime",
+ "key": " "
+ },
+ {
+ "type": "command",
+ "text": "date -d @$(stat -c %W /) '+%a %b %d %r %Z %Y'",
+ "key": " "
+ },
+
+ {
+ "type": "custom",
+ "format": "\u001b[1m—————————————————————————————————————"
+ },
+ {
+ "type": "custom",
+ "format": "\u001b[90m \u001b[31m \u001b[32m \u001b[33m \u001b[34m \u001b[35m \u001b[36m \u001b[37m"
+ }
+ ]
+ }
+ '';
+
+ # Small Neofetch config
+ pFetch = let
+ smallConf = pkgs.writeText "smallconf.jsonc" ''
+ {
+ "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
+ "logo": {
+ "source": "debian_small"
+ },
+ "modules": [
+ {
+ "type": "os",
+ "format": "{3} {12}",
+ "key": " "
+ },
+ {
+ "type": "host",
+ "format": "{5}",
+ "key": " "
+ },
+ {
+ "type": "kernel",
+ "format": "{1} {2}",
+ "key": " "
+ },
+ {
+ "type": "uptime",
+ "key": " "
+ },
+ {
+ "type": "packages",
+ "key": " "
+ },
+ {
+ "type": "memory",
+ "format": "{/1}{-}{/}{/2}{-}{/}{} / {}",
+ "key": " "
+ }
+ ]
+ }
+ '';
+ in pkgs.writeScriptBin "pfetch"
+ ''fastfetch --config ${smallConf}'';
+
+ # Rofi (terminal file browser) config
+ rangerConf = ''
+ set preview_script ~/.config/ranger/scope.sh
+ set preview_images true
+ set preview_images_method kitty
+ set dirname_in_tabs true
+ set cd_tab_fuzzy true
+ set autosave_bookmarks false
+ set show_hidden true
+ set wrap_scroll true
+ set column_ratios 2,2,4
+ set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$
+ default_linemode devicons
+ '';
+
+ # Choose how ranger opens stuff
+ rifleConf = ''
+ # Define the "editor" for text files as first action
+ mime ^text, label editor = nvim -- "$@"
+ mime ^text, label pager = "$PAGER" -- "$@"
+ !mime ^text, label editor, ext xml|json|csv|tex|py|pl|rb|js|sh|php = nvim -- "$@"
+ !mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@"
+
+ # Websites
+ ext x?html?, has librewolf, X, flag f = librewolf -- "$@"
+
+ # Define the "editor" for text files as first action
+ mime ^text, label editor = "$EDITOR" -- "$@"
+ mime ^text, label pager = "$PAGER" -- "$@"
+ !mime ^text, label editor, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$EDITOR" -- "$@"
+ !mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@"
+
+ # Misc files
+ ext 1 = man "$1"
+ ext exe = wine "$1"
+ ext msi = wine "$1"
+ name ^[mM]akefile$ = make
+
+ # Scripts
+ ext py = python -- "$1"
+ ext pl = perl -- "$1"
+ ext rb = ruby -- "$1"
+ ext js = node -- "$1"
+ ext sh = sh -- "$1"
+ ext php = php -- "$1"
+
+ # Audio and video
+ mime ^audio|ogg$, terminal, has mpv = mpv --no-audio-display -- "$@"
+ mime ^audio|ogg$, terminal, has mpv = mpv --shuffle --no-audio-display -- "$@"
+ mime ^video, has mpv, X, flag f = mpv -- "$@"
+ mime ^video, terminal, !X, has mpv = mpv -- "$@"
+
+ # Documents
+ ext pdf, has zathura, X, flag f = zathura -- "$@"
+ ext pdf, has xpdf, X, flag f = xpdf -- "$@"
+ ext pdf, has okular, X, flag f = okular -- "$@"
+ ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has libreoffice, X, flag f = libreoffice "$@"
+
+ # Images
+ mime ^image, has imv, X, flag f = imv -- "$@"
+
+ # Archives
+ ext 7z, has 7z = 7z -p l "$@" | "$PAGER"
+ ext 7z|ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has 7z = 7z x -- "$@"
+ ext iso|jar|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has 7z = 7z x -- "$@"
+
+ # Listing and extracting archives without atool:
+ ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | "$PAGER"
+ ext tar|gz|bz2|xz, has tar = for file in "$@"; do tar vvxf "$file"; done
+
+ # Fonts
+ mime ^font, has fontforge, X, flag f = fontforge "$@"
+
+ # Generic file openers
+ label open, has xdg-open = xdg-open -- "$@"
+
+ # Define the editor for non-text files + pager as last action
+ !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ask
+ label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$EDITOR" -- "$@"
+ label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@"
+
+ # Execute a file as program/script.
+ mime application/x-executable = "$1"
+ '';
+
+ # Ranger's preview
+ rangerScope = ''
+ #!/usr/bin/env bash
+ set -o noclobber -o noglob -o nounset -o pipefail
+ IFS=$'\n'
+
+ # Script arguments
+ FILE_PATH="$1"
+ PV_WIDTH="$2"
+ PV_HEIGHT="$3"
+ IMAGE_CACHE_PATH="$4"
+ PV_IMAGE_ENABLED="$5"
+
+ FILE_EXTENSION=$(echo "$FILE_PATH" | rev | cut -d. -f1 | rev)
+ FILE_EXTENSION_LOWER=$(echo "$FILE_EXTENSION" | tr '[:upper:]' '[:lower:]')
+
+ # Settings
+ HIGHLIGHT_TABWIDTH=8
+ HIGHLIGHT_STYLE='pablo'
+ PYGMENTIZE_STYLE='autumn'
+
+ handle_extension() {
+ case "$FILE_EXTENSION_LOWER" in
+ # Archive
+ a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\
+ rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)
+ atool --list -- "$FILE_PATH" && exit 5
+ bsdtar --list --file "$FILE_PATH" && exit 5
+ exit 1;;
+ rar)
+ unrar lt -p- -- "$FILE_PATH" && exit 5
+ exit 1;;
+ 7z)
+ 7z l -p -- "$FILE_PATH" && exit 5
+ exit 1;;
+ pdf)
+ pdftotext -l 10 -nopgbrk -q -- "$FILE_PATH" - && exit 5
+ exiftool "$FILE_PATH" && exit 5
+ exit 1;;
+ torrent)
+ transmission-show -- "$FILE_PATH" && exit 5
+ exit 1;;
+ # OpenDocument
+ odt|ods|odp|sxw)
+ odt2txt "$FILE_PATH" && exit 5
+ exit 1;;
+ esac
+ }
+
+ handle_image() {
+ local mimetype="$1"
+ case "$mimetype" in
+ # SVG
+ image/svg+xml)
+ convert "$FILE_PATH" "$IMAGE_CACHE_PATH" && exit 6
+ exit 1;;
+ # Image
+ image/*)
+ local orientation
+ orientation="$( identify -format '%[EXIF:Orientation]\n' -- "$FILE_PATH" )"
+ if [[ -n "$orientation" && "$orientation" != 1 ]]; then
+ convert -- "$FILE_PATH" -auto-orient "$IMAGE_CACHE_PATH" && exit 6
+ fi
+ exit 7;;
+ # Video
+ video/*)
+ # Thumbnail
+ ffmpegthumbnailer -i "$FILE_PATH" -o "$IMAGE_CACHE_PATH" -s 0 && exit 6
+ exit 1;;
+ # PDF
+ application/pdf)
+ pdftoppm -f 1 -l 1 \
+ -scale-to-x 1920 \
+ -scale-to-y -1 \
+ -singlefile \
+ -jpeg -tiffcompression jpeg \
+ -- "$FILE_PATH" "$(basename "$IMAGE_CACHE_PATH")" \
+ && exit 6 || exit 1;;
+ esac
+ }
+
+ handle_mime() {
+ local mimetype="$1"
+ case "$mimetype" in
+ # Text
+ text/* | */xml)
+ exit 2;;
+ # Image
+ image/*)
+ exiftool "$FILE_PATH" && exit 5
+ exit 1;;
+ # Video and audio
+ video/* | audio/*)
+ mediainfo "$FILE_PATH" && exit 5
+ exiftool "$FILE_PATH" && exit 5
+ exit 1;;
+ esac
+ }
+
+ MIMETYPE="$( file --dereference --brief --mime-type -- "$FILE_PATH" )"
+ if [[ "$PV_IMAGE_ENABLED" == 'True' ]]; then
+ handle_image "$MIMETYPE"
+ fi
+ handle_extension
+ handle_mime "$MIMETYPE"
+ handle_fallback
+ exit 1
+ '';
+
+ # Ranger's bookmarks
+ rangerBookmarks = ''
+ # Local files
+ k:/home/jimbo/Downloads
+ c:/home/jimbo/.config
+ L:/home/jimbo/.local
+ D:/mnt
+ n:/etc/nixos
+
+ # Remote files
+ a:/home/jimbo/JimboNFS
+ K:/home/jimbo/JimboNFS/Downloads
+ p:/home/jimbo/JimboNFS/Photos
+ V:/home/jimbo/JimboNFS/Videos/Random
+ m:/home/jimbo/JimboNFS/Music
+ L:/home/jimbo/JimboNFS/MineServers
+ s:/home/jimbo/JimboNFS/School
+ N:/home/jimbo/JimboNFS/JimboOS/NixOS
+ '';
+in
+
+{
+ # Define home manager programs and configs
+ home-manager = {
+ useGlobalPkgs = true;
+ useUserPackages = true;
+ users.jimbo = { config, pkgs, ... }: {
+ # Install user programs
+ home.packages = (with pkgs; [
+ fastfetch pFetch htop ranger tcptrack
+ ]);
+
+ # Install Neovim and plugins
+ programs.neovim = {
+ enable = true;
+ defaultEditor = true;
+ vimAlias = true;
+ plugins = with pkgs.vimPlugins; [
+ # Vim theme
+ vim-airline vim-airline-themes
+
+ # Internal clipboard
+ vim-vsnip cmp-vsnip
+
+ # Autocomplete manager
+ lspkind-nvim
+
+ # Autocomplete plugins
+ cmp-nvim-lsp cmp-buffer cmp-path cmp-cmdline nvim-cmp
+
+ # Hex color visualizer and color theme
+ nvim-colorizer-lua vim-monokai-pro
+ ];
+ extraConfig = ''
+ lua <'] = cmp.mapping.scroll_docs(-4),
+ [''] = cmp.mapping.scroll_docs(4),
+ [''] = cmp.mapping.complete(),
+ [''] = cmp.mapping.abort(),
+ [''] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
+ }),
+ sources = cmp.config.sources({
+ { name = 'nvim_lsp' },
+ { name = 'vsnip' }
+ }, {
+ { name = 'buffer' },
+ })
+ })
+
+ -- Use buffer source for `/` and `?`.
+ cmp.setup.cmdline({ '/', '?' }, {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = {
+ { name = 'buffer' }
+ }
+ })
+
+ -- Use cmdline & path source for ':'.
+ cmp.setup.cmdline(':', {
+ mapping = cmp.mapping.preset.cmdline(),
+ sources = cmp.config.sources({
+ { name = 'path' }
+ }, {
+ { name = 'cmdline' }
+ })
+ })
+ EOF
+
+ colorscheme monokai_pro
+ let g:airline_theme='onedark'
+ let g:airline#extensions#tabline#enabled = 1
+ highlight Normal guibg=none ctermbg=235
+ highlight Visual guibg=#151515 ctermbg=238
+ highlight Pmenu guibg=#151515 ctermbg=238
+ highlight EndOfBuffer guibg=none ctermbg=235
+ highlight LineNr guibg=none ctermbg=none
+ lua require'colorizer'.setup()
+
+ set nu rnu
+ set termguicolors
+ set runtimepath+=/usr/share/vim/vimfiles
+ set mouse=a
+
+ set undofile
+ set undodir=$HOME/.local/share/nvim/undo
+ set undolevels=100
+ set undoreload=10000
+
+ nmap :bnext
+ nmap :bprev
+ '';
+ };
+
+ # Enable tmux
+ programs.tmux = {
+ enable = true;
+ extraConfig = ''
+ set -g mouse on
+ set -g base-index 1
+ set -g default-terminal "st-256color"
+ set -g history-limit 4096
+ set -g set-titles on
+ set -g set-titles-string "#T"
+ set -g status on
+ set -g status-left ""
+ set -g status-position bottom
+ set -g status-right "#[bg=brightblack]#[fg=dark_purple] #T "
+ set -g status-style "bg=black"
+ setw -g pane-base-index 1
+ setw -g window-status-format "#[bg=brightmagenta]#[fg=black] #I #[bg=brightblack]#[fg=white] #W "
+ setw -g window-status-current-format "#[bg=brightmagenta]#[fg=black] #I #[bg=white]#[fg=black] #W "
+ '';
+ };
+
+ # Start defining arbitrary files
+ home.file = {
+ # Fastfetch config
+ ".config/fastfetch/config.jsonc".text = neoConf;
+
+ # Ranger config
+ ".config/ranger/rc.conf".text = rangerConf;
+ ".config/ranger/rifle.conf".text = rifleConf;
+ ".config/ranger/scope.sh" = { text = rangerScope; executable = true; };
+ ".local/share/ranger/bookmarks".text = rangerBookmarks;
+ ".config/ranger/plugins/devicons/devicons.py".source = "${pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/alexanderjeurissen/ranger_devicons/2c3c19dffb4238d01c74515c9eed5088066db243/devicons.py";
+ sha256 = "0girsranwhsgc6kcyh1mkwymx0bl14a2k5nzk3kyllb6ic48c33k";
+ }}";
+ ".config/ranger/plugins/devicons/__init__.py".source = "${pkgs.fetchurl {
+ url = "https://raw.githubusercontent.com/alexanderjeurissen/ranger_devicons/2c3c19dffb4238d01c74515c9eed5088066db243/__init__.py";
+ sha256 = "1r086apw20ryxylqgnbynx7mzz779v1w0m40wghmmhlzw4x15fmr";
+ }}";
+ };
+
+ # Shell aliases
+ programs.zsh = {
+ enable = true;
+ autosuggestion.enable = true;
+ syntaxHighlighting.enable = true;
+ initExtra = ''
+ ${pkgs.any-nix-shell}/bin/any-nix-shell zsh --info-right | source /dev/stdin; pfetch
+ '';
+ oh-my-zsh = {
+ enable = true;
+ plugins = [ "git" ];
+ theme = "half-life";
+ };
+ shellAliases = let
+ mineServers = ''/home/jimbo/JimboNFS/MineServers'';
+ in {
+ # NixOS aliases
+ nixcfg = "nvim /etc/nixos/{configuration,jimbo,hardware-configuration}.nix";
+ nixswitch = "${auth} nixos-rebuild switch";
+ nixdate = "${auth} nixos-rebuild switch --upgrade-all";
+ nixclean = "${auth} nix-store --gc; nix-collect-garbage -d";
+
+ # Shortcut aliases
+ neo = "clear && fastfetch";
+ ip = "ip -c";
+ ls = "${pkgs.eza}/bin/eza -a --color=always --group-directories-first --icons";
+ cat = "${pkgs.bat}/bin/bat --paging never";
+
+ # Curl tools
+ myip = "curl ifconfig.co";
+
+ # Start basic programs
+ controlpanel = "tmux new-session -d -s control; tmux attach -t control";
+
+ # Minecraft stuff
+ mcstart21 = "${pkgs.temurin-jre-bin-21}/bin/java -Xmx8G -jar";
+ mcstart8 = "${pkgs.temurin-jre-bin-8}/bin/java -Xmx5G -jar";
+ velocitystart = "cd ${mineServers}/Velocity && mcstart21 velocity*";
+ johnstart = "cd ${mineServers}/Johnside-SMP && mcstart21 paper* --nogui";
+ bloxelstart = "cd ${mineServers}/Bloxelcom && mcstart21 paper* --nogui";
+ dewstart = "cd ${mineServers}/DewDestroyer && mcstart21 paper* --nogui";
+ betastart = "cd ${mineServers}/BetaServer && mcstart8 Posiden*";
+ };
+ };
+
+ # Define current version
+ home.stateVersion = "23.11";
+ };
+ };
+}