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"; + }; + }; +}