From d8c9631d3ba10929c0b030977041ab42c4cfaff4 Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 29 Feb 2024 09:53:34 -0500 Subject: [PATCH] Initial public commit! --- .gitignore | 2 + README.md | 95 + flake.lock | 322 +++ flake.nix | 89 + hosts/Dimaga/default.nix | 45 + hosts/Dimaga/hardware-configuration.nix | 48 + hosts/Haven/default.nix | 66 + hosts/Haven/hardware-configuration.nix | 52 + hosts/Haven/start-haven.sh | 46 + hosts/Pihole/default.nix | 43 + hosts/Pihole/hardware-configuration.nix | 42 + .../bluetooth/mano-touchpad-bluetooth-params | 31 + .../bluetooth/shure-aonic-bluetooth-params | 19 + .../xbox-elite-controller-bluetooth-params | 38 + hosts/Shura/default.nix | 104 + hosts/Shura/hardware-configuration.nix | 95 + hosts/Shura/monitors.xml | 60 + .../legion_7i-gen7-16IAX7-sound-6.7.3.patch | 32 + ...o-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch | 134 ++ hosts/common/default.nix | 15 + hosts/default.nix | 8 + modules/apps/default.nix | 12 + modules/apps/development.nix | 20 + modules/apps/dj.nix | 19 + modules/apps/gaming.nix | 20 + modules/apps/hugo.nix | 19 + modules/apps/media.nix | 28 + modules/apps/office.nix | 20 + modules/apps/pandoc.nix | 20 + modules/apps/recording.nix | 36 + modules/base/bluetooth.nix | 60 + modules/base/bootloader.nix | 58 + modules/base/default.nix | 9 + modules/base/network.nix | 12 + modules/base/shell.nix | 7 + modules/base/system.nix | 163 ++ modules/default.nix | 10 + modules/packages/duplicacy-web.nix | 27 + modules/roles/default.nix | 18 + modules/roles/server.nix | 15 + modules/roles/workstation.nix | 35 + modules/services/apcupsd.nix | 17 + modules/services/default.nix | 8 + modules/services/duplicacy-web.nix | 52 + modules/services/etc/apcupsd.conf | 333 +++ modules/services/k3s.nix | 57 + modules/services/msmtp.nix | 25 + modules/ui/audio.nix | 33 + modules/ui/default.nix | 9 + modules/ui/flatpak.nix | 65 + modules/ui/gnome.nix | 122 ++ modules/users/aires/default.nix | 156 ++ modules/users/common/gnome.nix | 51 + modules/users/default.nix | 7 + modules/users/gremlin/default.nix | 125 ++ modules/users/gremlin/p10k-config/p10k.zsh | 1781 +++++++++++++++++ modules/users/media/default.nix | 29 + 57 files changed, 4864 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hosts/Dimaga/default.nix create mode 100644 hosts/Dimaga/hardware-configuration.nix create mode 100644 hosts/Haven/default.nix create mode 100644 hosts/Haven/hardware-configuration.nix create mode 100644 hosts/Haven/start-haven.sh create mode 100644 hosts/Pihole/default.nix create mode 100644 hosts/Pihole/hardware-configuration.nix create mode 100644 hosts/Shura/bluetooth/mano-touchpad-bluetooth-params create mode 100644 hosts/Shura/bluetooth/shure-aonic-bluetooth-params create mode 100644 hosts/Shura/bluetooth/xbox-elite-controller-bluetooth-params create mode 100644 hosts/Shura/default.nix create mode 100644 hosts/Shura/hardware-configuration.nix create mode 100644 hosts/Shura/monitors.xml create mode 100644 hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch create mode 100644 hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch create mode 100644 hosts/common/default.nix create mode 100644 hosts/default.nix create mode 100644 modules/apps/default.nix create mode 100644 modules/apps/development.nix create mode 100644 modules/apps/dj.nix create mode 100644 modules/apps/gaming.nix create mode 100644 modules/apps/hugo.nix create mode 100644 modules/apps/media.nix create mode 100644 modules/apps/office.nix create mode 100644 modules/apps/pandoc.nix create mode 100644 modules/apps/recording.nix create mode 100644 modules/base/bluetooth.nix create mode 100644 modules/base/bootloader.nix create mode 100644 modules/base/default.nix create mode 100644 modules/base/network.nix create mode 100644 modules/base/shell.nix create mode 100644 modules/base/system.nix create mode 100644 modules/default.nix create mode 100644 modules/packages/duplicacy-web.nix create mode 100644 modules/roles/default.nix create mode 100644 modules/roles/server.nix create mode 100644 modules/roles/workstation.nix create mode 100644 modules/services/apcupsd.nix create mode 100644 modules/services/default.nix create mode 100644 modules/services/duplicacy-web.nix create mode 100644 modules/services/etc/apcupsd.conf create mode 100644 modules/services/k3s.nix create mode 100644 modules/services/msmtp.nix create mode 100644 modules/ui/audio.nix create mode 100644 modules/ui/default.nix create mode 100644 modules/ui/flatpak.nix create mode 100644 modules/ui/gnome.nix create mode 100644 modules/users/aires/default.nix create mode 100644 modules/users/common/gnome.nix create mode 100644 modules/users/default.nix create mode 100644 modules/users/gremlin/default.nix create mode 100644 modules/users/gremlin/p10k-config/p10k.zsh create mode 100644 modules/users/media/default.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0214a90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.qcow2 +result \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2b618e --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# NixOS Configuration + +A full set of configuration files managed via NixOS. This project follows the general structure of https://github.com/tiredofit/nixos-config + +## Running + +### Note on secrets management + +Secrets are stored in a separate repo called `nix-secrets`, which gets pulled automagically for all configs. See `hosts/common/default.nix`. This is a poor man's secret management solution, but y'know what, it works. These "secrets" will be readable to users on the system with access to the `/nix/store/`, but for single-user systems, it's fine. + +### Building the system + +When using nix-secrets, we need to separate the build process into two steps (because of secrets being stored in a private repo; the alternative is to give root access to the private repo on all hosts). First step is to create the build by running this as `aires`: + +```zsh +nixos-rebuild build --flake .#Shura +``` + +When the build is done, run this command as root: + +```zsh +sudo ./result/bin/switch-to-configuration switch +``` + +`switch` replaces the running system immediately, or you can use `boot` to only apply the switch during the next reboot. After applying the build at least once (or setting the hostname manually), you can omit the hostname from the command and just run `nixos-rebuild build --flake .` + +#### Normal build process + +Normally (without a secret GitHub repo) you'd just use `sudo nixos-rebuild` like so: + +```zsh +sudo nixos-rebuild switch --flake .#Shura +``` + +### Testing + +To quickly validate the configuration, create a dry build. This builds the config without actually adding it to the system: + +```zsh +nixos-rebuild dry-build --flake . +``` + +To preview changes in a virtual machine, use this command to create a virtual machine image (remove the .qcow2 image after a while, otherwise data persistence might mess things up): + +```zsh +nixos-rebuild build-vm --flake . +``` + +### Updating + +`flake.lock` locks the version of any packages/modules used. To update them, run `nix flake update` first: + +```zsh +nix flake update && nixos-rebuild build --flake . && sudo ./result/bin/switch-to-configuration switch +``` + +Home-manager also installs a ZSH alias, so you can just run `update` or `upgrade` for the same effect. + +## Layout + +This config uses two systems: Flakes, and Home-manager. + +- Flakes are the entrypoint, via `flake.nix`. This is where you include Flake modules and define Flake-specific options. +- Home-manager configs live in the `users/` folders. Each user gets its own `home-manager.nix` file too. +- Modules are stored in `modules`. All of these files are imported, and you enable the ones you want to use. For example, to install Flatpak, set `host.ui.flatpak.enable = true;`. + - After adding a new module, make sure to `git add` it _and_ `import` it in `default.nix`. + +### Adding a host + +When adding a host: + +1. Create its config in `hosts/hostname/.nix`. Add its `hardware-configuration.nix` here too. +2. Reference a profile from `profiles/`. This sets up its base configuration. +3. Include user accounts from `users`. +4. Add any host-specific options, +5. Import it in `/hosts/default.nix`. +6. Run `nixos-rebuild`. + +## Features + +This Nix config features: + +- Flakes +- Home Manager +- AMD and Intel hardware configurations +- Workstation and server base system configurations +- GNOME Desktop environment and KDE integrations +- Boot splash screens via Plymouth +- Secure Boot +- Disk encryption via LUKS +- Custom packages and systemd services (Duplicacy) +- Flatpaks +- Per-user configurations +- Default ZSH shell using Oh My ZSH +- Secrets (in a janky hacky kinda way) \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..8ad5dd2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,322 @@ +{ + "nodes": { + "crane": { + "inputs": { + "flake-compat": [ + "lanzaboote", + "flake-compat" + ], + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ], + "rust-overlay": [ + "lanzaboote", + "rust-overlay" + ] + }, + "locked": { + "lastModified": 1681177078, + "narHash": "sha256-ZNIjBDou2GOabcpctiQykEQVkI8BDwk7TyvlWlI4myE=", + "owner": "ipetkov", + "repo": "crane", + "rev": "0c9f468ff00576577d83f5019a66c557ede5acf6", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1680392223, + "narHash": "sha256-n3g7QFr85lDODKt250rkZj2IFS3i4/8HBU2yKHO3tqw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "dcc36e45d054d7bb554c9cdab69093debd91a0b5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "pre-commit-hooks-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709204054, + "narHash": "sha256-U1idK0JHs1XOfSI1APYuXi4AEADf+B+ZU4Wifc0pBHk=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "2f3367769a93b226c467551315e9e270c3f78b15", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "pre-commit-hooks-nix": "pre-commit-hooks-nix", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1682802423, + "narHash": "sha256-Fb5TeRTdvUlo/5Yi2d+FC8a6KoRLk2h1VE0/peMhWPs=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "64b903ca87d18cef2752c19c098af275c6e51d63", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "v0.3.0", + "repo": "lanzaboote", + "type": "github" + } + }, + "nix-flatpak": { + "locked": { + "lastModified": 1708268179, + "narHash": "sha256-NNVuhf84AeDTxadfSGnFqPHR0ED+QyM2gmu+Wyz6PrY=", + "owner": "gmodena", + "repo": "nix-flatpak", + "rev": "a243cb0522f6240c194b873dde68e25370b06034", + "type": "github" + }, + "original": { + "owner": "gmodena", + "ref": "v0.3.0", + "repo": "nix-flatpak", + "type": "github" + } + }, + "nixos-hardware": { + "locked": { + "lastModified": 1709147990, + "narHash": "sha256-vpXMWoaCtMYJ7lisJedCRhQG9BSsInEyZnnG5GfY9tQ=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "33a97b5814d36ddd65ad678ad07ce43b1a67f159", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "master", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1682741954, + "narHash": "sha256-RPZxzRu8XU0YD2WeYUFYzJy5yAvWUsxkuK+zWw+6WVk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "373e9eb4c42b2fc0611d794de5ea715a35d72393", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1678872516, + "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1709150264, + "narHash": "sha256-HofykKuisObPUfj0E9CJVfaMhawXkYx3G8UIFR/XQ38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9099616b93301d5cf84274b184a3a5ec69e94e08", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks-nix": { + "inputs": { + "flake-compat": [ + "lanzaboote", + "flake-compat" + ], + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1681413034, + "narHash": "sha256-/t7OjNQcNkeWeSq/CFLYVBfm+IEnkjoSm9iKvArnUUI=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "d3de8f69ca88fb6f8b09e5b598be5ac98d28ede5", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "lanzaboote": "lanzaboote", + "nix-flatpak": "nix-flatpak", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs_2" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1682129965, + "narHash": "sha256-1KRPIorEL6pLpJR04FwAqqnt4Tzcm4MqD84yhlD+XSk=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "2c417c0460b788328220120c698630947547ee83", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..5b5a874 --- /dev/null +++ b/flake.nix @@ -0,0 +1,89 @@ +# For info on Flakes, see: https://nixos-and-flakes.thiscute.world/nixos-with-flakes/nixos-with-flakes-enabled + +{ + description = "Aires' system Flake"; + + inputs = { + # Configure nixpkgs + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + # For SecureBoot support + lanzaboote.url = "github:nix-community/lanzaboote/v0.3.0"; + + # For Flatpak support + nix-flatpak.url = "github:gmodena/nix-flatpak/v0.3.0"; # Use github:gmodena/nix-flatpak/?ref= to change release version, nix-flatpak/ to reference a specific commit, or remove to track main (unstable). + + # Hardware configurations + nixos-hardware.url = "github:NixOS/nixos-hardware/master"; + + # Home-manager + home-manager = { + url = "github:nix-community/home-manager/master"; + inputs.nixpkgs.follows = "nixpkgs"; # Use system packages list where available + }; + }; + + outputs = inputs@{ self, nixpkgs, lanzaboote, nix-flatpak, home-manager, nixos-hardware, ... }: + let + inherit (self) outputs; + lib = nixpkgs.lib; + systems = [ "x86_64-linux" "aarch64-linux" ]; + forEachSystem = f: lib.genAttrs systems (sys: f pkgsFor.${sys}); + pkgsFor = lib.genAttrs systems (system: import nixpkgs { + inherit system; + config.allowUnfree = true; + }); + + # Define shared modules and imports + defaultModules = { + base = [ + { _module.args = { inherit inputs; }; } + lanzaboote.nixosModules.lanzaboote + nix-flatpak.nixosModules.nix-flatpak + home-manager.nixosModules.home-manager { + home-manager = { + /* + When running, Home Manager will use the global package cache. + It will also back up any files that it would otherwise overwrite. + The originals will have the extension shown below. + */ + useGlobalPkgs = true; + useUserPackages = true; + backupFileExtension = "home-manager-backup"; + }; + } + ]; + }; + in { + nixosConfigurations = { + Dimaga = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = defaultModules.base ++ [ + ./hosts/Dimaga + ]; + }; + + Haven = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = defaultModules.base ++ [ + ./hosts/Haven + ]; + }; + + Pihole = nixpkgs.lib.nixosSystem { + system = "aarch64-linux"; + modules = defaultModules.base ++ [ + nixos-hardware.nixosModules.raspberry-pi-4 + ./hosts/Pihole + ]; + }; + + Shura = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = defaultModules.base ++ [ + ./hosts/Shura + ]; + }; + }; + }; + } diff --git a/hosts/Dimaga/default.nix b/hosts/Dimaga/default.nix new file mode 100644 index 0000000..f9d245d --- /dev/null +++ b/hosts/Dimaga/default.nix @@ -0,0 +1,45 @@ +{ pkgs, ... }: + +# Settings specific to Dimaga + +{ + imports = [ + ./hardware-configuration.nix + ../common + ]; + + system.stateVersion = "24.05"; + + host = { + role = "workstation"; + apps = { + development.enable = true; + hugo.enable = true; + media.enable = true; + office.enable = true; + pandoc.enable = true; + }; + ui = { + flatpak.enable = true; + gnome.enable = true; + }; + users = { + aires = { + enable = true; + autologin = true; + services = { + syncthing = { + enable = true; + autostart = true; + }; + }; + }; + }; + }; + + # Configure the virtual machine created by nixos-rebuild build-vm + virtualisation.vmVariant.virtualisation = { + memorySize = 2048; + cores = 2; + }; +} \ No newline at end of file diff --git a/hosts/Dimaga/hardware-configuration.nix b/hosts/Dimaga/hardware-configuration.nix new file mode 100644 index 0000000..955619f --- /dev/null +++ b/hosts/Dimaga/hardware-configuration.nix @@ -0,0 +1,48 @@ +# Surface Laptop Go +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot = { + initrd = { + availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "usbhid" "sd_mod" ]; + kernelModules = [ ]; + luks.devices."luks-5a91100b-8ed9-4090-b1d8-d8291000fe38".device = "/dev/disk/by-uuid/5a91100b-8ed9-4090-b1d8-d8291000fe38"; + }; + + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/76d67291-5aed-4f2a-b71f-1c2871cefe24"; + fsType = "btrfs"; + options = [ "subvol=@" ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/0C53-A645"; + fsType = "vfat"; + }; + }; + + swapDevices = [ ]; + + networking = { + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + useDHCP = lib.mkDefault true; + # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true; + + # Set the hostname. + hostName = "Dimaga"; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/Haven/default.nix b/hosts/Haven/default.nix new file mode 100644 index 0000000..a8f1f35 --- /dev/null +++ b/hosts/Haven/default.nix @@ -0,0 +1,66 @@ +{ pkgs, home-manager, lib, config, ... }: + +# Settings specific to Haven + +let + start-haven = pkgs.writeText "info" (builtins.readFile ./start-haven.sh); +in +{ + imports = [ + ./hardware-configuration.nix + ../common + ]; + + system.stateVersion = "24.05"; + + host = { + role = "server"; + services = { + apcupsd.enable = true; + duplicacy-web = { + enable = true; + autostart = false; + environment = "${config.users.users.aires.home}"; + }; + k3s = { + enable = true; + role = "server"; + }; + msmtp.enable = true; + }; + users = { + aires = { + enable = true; + services = { + syncthing = { + enable = true; + autostart = false; + }; + }; + }; + media.enable = true; + }; + }; + + # Enable SSH + services.openssh = { + enable = true; + ports = [ 33105 ]; + + settings = { + # require public key authentication for better security + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + PubkeyAuthentication = true; + + PermitRootLogin = "without-password"; + }; + }; + + # Add script for booting Haven + systemd.tmpfiles.rules = [ + "d ${config.users.users.aires.home}/bin/ 0700 aires users" # First, make sure the directory exists + "L+ ${config.users.users.aires.home}/bin/start-haven 0700 - - - ${start-haven}" + ]; + +} \ No newline at end of file diff --git a/hosts/Haven/hardware-configuration.nix b/hosts/Haven/hardware-configuration.nix new file mode 100644 index 0000000..e5f6d76 --- /dev/null +++ b/hosts/Haven/hardware-configuration.nix @@ -0,0 +1,52 @@ +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + boot = { + supportedFilesystems = [ "btrfs" ]; + kernelModules = [ "kvm-amd" ]; + extraModulePackages = [ ]; + + initrd = { + supportedFilesystems = [ "btrfs" ]; + availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" "btrfs" ]; + kernelModules = [ ]; + }; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-uuid/2c76c660-3573-4622-8771-f23fa7ee302a"; + fsType = "btrfs"; + options = [ "subvol=@,compress=zstd" ]; + }; + "/home" = { + device = "/dev/disk/by-uuid/2c76c660-3573-4622-8771-f23fa7ee302a"; + fsType = "btrfs"; + options = [ "subvol=@home,compress=zstd" ]; + }; + "/swap" = { + device = "/dev/disk/by-uuid/2c76c660-3573-4622-8771-f23fa7ee302a"; + fsType = "btrfs"; + options = [ "subvol=@swap" ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/0120-A755"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ + device = "/swap/swapfile"; + }]; + + networking = { + useDHCP = lib.mkDefault true; + hostName = "Haven"; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/Haven/start-haven.sh b/hosts/Haven/start-haven.sh new file mode 100644 index 0000000..c1b4c1b --- /dev/null +++ b/hosts/Haven/start-haven.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# Script to unlock the /storage partition and start up services that depend on it. + +# check if the current user is root +if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +# Immediately exit on any errors +set -e + +# local storage partition +echo "Unlocking storage partition:" +cryptsetup luksOpen /dev/disk/by-uuid/223582c7-fbad-467d-8f85-4d4cebd3230c storage + +# mount local storage +if [ ! -f /dev/mapper/storage ]; then + mount /dev/mapper/storage /storage + + if [ $? -eq "0" ]; then + echo "Storage and backup partitions mounted." + + echo "Starting Duplicacy:" + systemctl start duplicacy-web.service + if [ $? -eq "0" ]; then + echo "Duplicacy started." + else + echo "Failed to start Duplicacy." + fi + + echo "Starting SyncThing:" + systemctl --user -M aires@ start syncthing.service + if [ $? -eq "0" ]; then + echo "SyncThing started." + else + echo "Failed to start SyncThing." + fi + else + echo "Failed to mount storage partition." + fi +else + echo "Failed to unlock storage and/or backup partition(s)." +fi + +exit 0 \ No newline at end of file diff --git a/hosts/Pihole/default.nix b/hosts/Pihole/default.nix new file mode 100644 index 0000000..692a216 --- /dev/null +++ b/hosts/Pihole/default.nix @@ -0,0 +1,43 @@ +{ pkgs, lib, ... }: + +# Settings specific to Raspberry Pi 4b + +{ + imports = [ + ./hardware-configuration.nix + ../common + ]; + + system.stateVersion = "24.05"; + + host = { + role = "server"; + users.aires.enable = true; + boot.enable = false; + }; + + networking.hostName = "Pihole"; + time.timeZone = "America/New_York"; + + environment.systemPackages = with pkgs; [ + libraspberrypi + raspberrypifw + raspberrypi-eeprom + linuxKernel.kernels.linux_rpi4 + ]; + + # Connect to the network automagically + networking.networkmanager.enable = lib.mkForce false; + + # Enable SSH + services.openssh = { + enable = true; + ports = [ 33105 ]; + + settings = { + PasswordAuthentication = true; + AllowUsers = ["aires"]; + PermitRootLogin = "no"; + }; + }; +} diff --git a/hosts/Pihole/hardware-configuration.nix b/hosts/Pihole/hardware-configuration.nix new file mode 100644 index 0000000..cf5a5ae --- /dev/null +++ b/hosts/Pihole/hardware-configuration.nix @@ -0,0 +1,42 @@ +# Raspberry Pi 4 +# See https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_4 +{ config, lib, pkgs, modulesPath, nixos-hardware, ... }: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.loader = lib.mkForce { + grub.enable = false; + generic-extlinux-compatible.enable = true; + }; + + #boot.kernelParams = [ + # "console=serial0,115200n8" + #]; + + fileSystems ."/" = { + device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; + fsType = "ext4"; + }; + + swapDevices = [{ + device = "/swapfile"; + size = 2048; + }]; + + hardware.enableRedistributableFirmware = true; + networking.wireless.enable = true; + + hardware = { + raspberry-pi."4" = { + apply-overlays-dtmerge.enable = true; + }; + + deviceTree = { + enable = true; + filter = "*rpi-4-*.dtb"; + }; + }; +} diff --git a/hosts/Shura/bluetooth/mano-touchpad-bluetooth-params b/hosts/Shura/bluetooth/mano-touchpad-bluetooth-params new file mode 100644 index 0000000..6e6be7a --- /dev/null +++ b/hosts/Shura/bluetooth/mano-touchpad-bluetooth-params @@ -0,0 +1,31 @@ +[General] +Name=MANO-703UB V2_BLE +Appearance=0x03c1 +AddressType=static +SupportedTechnologies=LE; +Trusted=true +Blocked=false +WakeAllowed=true +Services=00001800-0000-1000-8000-00805f9b34fb;0000180a-0000-1000-8000-00805f9b34fb;0000180f-0000-1000-8000-00805f9b34fb;00001812-0000-1000-8000-00805f9b34fb;0000ff00-0000-1000-8000-00805f9b34fb; + +[ConnectionParameters] +MinInterval=6 +MaxInterval=6 +Latency=9 +Timeout=200 + +[IdentityResolvingKey] +Key=10943ED4C3FD489941E66426DB4C2479 + +[LongTermKey] +Key=9EEF52460DD57A878A1629B814361EDC +Authenticated=0 +EncSize=16 +EDiv=35588 +Rand=8974202121033153697 + +[DeviceID] +Source=2 +Vendor=8654 +Product=24577 +Version=17 diff --git a/hosts/Shura/bluetooth/shure-aonic-bluetooth-params b/hosts/Shura/bluetooth/shure-aonic-bluetooth-params new file mode 100644 index 0000000..94a2312 --- /dev/null +++ b/hosts/Shura/bluetooth/shure-aonic-bluetooth-params @@ -0,0 +1,19 @@ +[General] +Name=Shure AONIC TW2 +Class=0x2c0404 +SupportedTechnologies=BR/EDR;LE; +Trusted=true +Blocked=false +Services=00001101-0000-1000-8000-00805f9b34fb;00001108-0000-1000-8000-00805f9b34fb;0000110a-0000-1000-8000-00805f9b34fb;0000110b-0000-1000-8000-00805f9b34fb;0000110c-0000-1000-8000-00805f9b34fb;0000110d-0000-1000-8000-00805f9b34fb;0000110e-0000-1000-8000-00805f9b34fb;0000111e-0000-1000-8000-00805f9b34fb;0000eb03-d102-11e1-9b23-00025b00a5a5;0000eb04-d102-11e1-9b23-00025b00a5a5;0000eb05-d102-11e1-9b23-00025b00a5a5; +AddressType=public + +[LinkKey] +Key=DFC42899B038D6C6B1296CF98DB0508A +Type=4 +PINLength=0 + +[ConnectionParameters] +MinInterval=24 +MaxInterval=40 +Latency=0 +Timeout=400 diff --git a/hosts/Shura/bluetooth/xbox-elite-controller-bluetooth-params b/hosts/Shura/bluetooth/xbox-elite-controller-bluetooth-params new file mode 100644 index 0000000..fa482d5 --- /dev/null +++ b/hosts/Shura/bluetooth/xbox-elite-controller-bluetooth-params @@ -0,0 +1,38 @@ +[General] +Name=Xbox Wireless Controller +Appearance=0x03c4 +AddressType=public +SupportedTechnologies=LE; +Trusted=true +Blocked=false +WakeAllowed=true +Services=00000001-5f60-4c4f-9c83-a7953298d40d;00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;0000180a-0000-1000-8000-00805f9b34fb;0000180f-0000-1000-8000-00805f9b34fb;00001812-0000-1000-8000-00805f9b34fb; + +[IdentityResolvingKey] +Key=763775163AD76AF443DAEAEBCCED3776 + +[PeripheralLongTermKey] +Key=BE68B197C7F98340A5A40DEF3EBE4545 +Authenticated=2 +EncSize=16 +EDiv=0 +Rand=0 + +[SlaveLongTermKey] +Key=BE68B197C7F98340A5A40DEF3EBE4545 +Authenticated=2 +EncSize=16 +EDiv=0 +Rand=0 + +[ConnectionParameters] +MinInterval=6 +MaxInterval=6 +Latency=0 +Timeout=300 + +[DeviceID] +Source=2 +Vendor=1118 +Product=2850 +Version=1301 diff --git a/hosts/Shura/default.nix b/hosts/Shura/default.nix new file mode 100644 index 0000000..79da5ff --- /dev/null +++ b/hosts/Shura/default.nix @@ -0,0 +1,104 @@ +{ config, pkgs, lib, ... }: + +# Configuration options unique to Shura + +let + # Copy bluetooth device configs + shure-aonic-bluetooth = pkgs.writeText "info" (builtins.readFile ./bluetooth/shure-aonic-bluetooth-params); + xbox-elite-bluetooth = pkgs.writeText "info" (builtins.readFile ./bluetooth/xbox-elite-controller-bluetooth-params); + mano-touchpad-bluetooth = pkgs.writeText "info" (builtins.readFile ./bluetooth/mano-touchpad-bluetooth-params); + + # Use gremlin user's monitor configuration for GDM (desktop monitor primary). See https://discourse.nixos.org/t/gdm-monitor-configuration/6356/4 + monitorsXmlContent = builtins.readFile ./monitors.xml; + monitorsConfig = pkgs.writeText "gdm_monitors.xml" monitorsXmlContent; +in +{ + imports = [ + ./hardware-configuration.nix + ../common + ]; + + system.stateVersion = "24.05"; + + host = { + role = "workstation"; + apps = { + development.enable = true; + dj.enable = true; + gaming.enable = true; + hugo.enable = true; + media.enable = true; + office.enable = true; + pandoc.enable = true; + recording.enable = true; + }; + ui = { + flatpak.enable = true; + gnome.enable = true; + }; + users = { + aires = { + enable = true; + services.syncthing = { + enable = true; + enableTray = true; + }; + }; + gremlin = { + enable = true; + services.syncthing = { + enable = true; + enableTray = true; + }; + }; + }; + }; + + # Configure users + users.users = { + aires = { + extraGroups = [ "libvirt" "gremlin" ]; + }; + gremlin = { + extraGroups = [ "libvirt" ]; + }; + }; + + # Add packages specific to Shura + environment.systemPackages = with pkgs; [ + kubectl + kubevirt # Virtctl command-line tool + linuxKernel.packages.linux_zen.xpadneo # Xbox controller driver + ]; + + # Move files into target system + systemd.tmpfiles.rules = [ + # Use gremlin user's monitor config for GDM (defined above) + "L+ /run/gdm/.config/monitors.xml - - - - ${monitorsConfig}" + + # Install Bluetooth device profiles + "d /var/lib/bluetooth/AC:50:DE:9F:AB:88/ 0700 root root" # First, make sure the directory exists + "L+ /var/lib/bluetooth/AC:50:DE:9F:AB:88/00:0E:DD:72:2F:0C/info - - - - ${shure-aonic-bluetooth}" + "L+ /var/lib/bluetooth/AC:50:DE:9F:AB:88/F4:6A:D7:3A:16:75/info - - - - ${xbox-elite-bluetooth}" + "L+ /var/lib/bluetooth/AC:50:DE:9F:AB:88/F8:5D:3C:7D:9A:00/info - - - - ${mano-touchpad-bluetooth}" + ]; + + # Configure the virtual machine created by nixos-rebuild build-vm + virtualisation.vmVariant.virtualisation = { + memorySize = 4096; + cores = 4; + }; + + # FIXME: Add extra boot entry for the recovery image. This doesn't work with lanzaboote though :( + # NixOS config: https://nixos.org/manual/nixos/stable/options.html#opt-boot.loader.systemd-boot.extraEntries + # Systemd-boot config: https://wiki.archlinux.org/title/Systemd-boot#Adding_loaders + # Booting an ISO from disk: https://www.reddit.com/r/archlinux/comments/qy281v/boot_an_archlinux_iso_directly_from_my_boot_using/ + boot.loader.systemd-boot.extraEntries = { + "nixos-live.conf" = '' + title NixOS + linux /live/vmlinuz-linux + initrd /live/initramfs-linux.img + options img_dev=/dev/nvme0n1p3 img_loop=nixos-gnome-23.11.3019.8bf65f17d807-x86_64-linux.isosudo copytoram + ''; + }; +} diff --git a/hosts/Shura/hardware-configuration.nix b/hosts/Shura/hardware-configuration.nix new file mode 100644 index 0000000..1115583 --- /dev/null +++ b/hosts/Shura/hardware-configuration.nix @@ -0,0 +1,95 @@ +# Lenovo Legion S7 16ARHA7 configuration +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + # Configure the kernel. + boot = { + # First, install the latest Zen kernel + kernelPackages = pkgs.linuxPackages_zen; + + # Hardware defaults detected by nixos-generate-configuration + initrd = { + # SystemD in the initrd is required for TPM auto-unlocking. + # See https://discourse.nixos.org/t/full-disk-encryption-tpm2/29454/2 + # If the LUKS volume is recently created, run this command to bind it to the TPM: + # sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/ + systemd.enable = true; + + availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" "tpm_crb" ]; + kernelModules = [ "amdgpu" "tpm_crb" ]; + luks.devices."luks-bcf67e34-339e-40b9-8ffd-bec8f7f55248" = { + device = "/dev/disk/by-uuid/bcf67e34-339e-40b9-8ffd-bec8f7f55248"; + crypttabExtraOpts = [ "tpm2-device=auto" ]; # Enable TPM auto-unlocking + }; + }; + + kernelModules = [ + "kvm-amd" + "hid_xpadneo" + ]; + + # Add XPadNeo + extraModulePackages = with config.boot.kernelPackages; [ xpadneo ]; + + # Add kernel patch to enable sound over the speakers. + # This might not be necessary for long - see https://forums.lenovo.com/topic/findpost/27/5258964/6212600 + #kernelPatches = [{ + # name = "legion-speaker-fix"; + # patch = ./patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch; + #}]; + }; + + fileSystems = { + "/" = { device = "/dev/disk/by-uuid/b801fbea-4cb5-4255-bea9-a2ce77d1a1b7"; + fsType = "btrfs"; + options = [ "subvol=@,compress=zstd" ]; + }; + "/home" = { device = "/dev/disk/by-uuid/b801fbea-4cb5-4255-bea9-a2ce77d1a1b7"; + fsType = "btrfs"; + options = [ "subvol=@home,compress=zstd" ]; + }; + "/swap" = { device = "/dev/disk/by-uuid/b801fbea-4cb5-4255-bea9-a2ce77d1a1b7"; + fsType = "btrfs"; + options = [ "subvol=@swap" ]; + }; + "/boot" = { + device = "/dev/disk/by-uuid/AFCB-D880"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ + device = "/swap/swapfile"; + }]; + + # Enable AMDGPU + hardware = { + opengl = { + driSupport = true; # This is already enabled by default, but just in case. + driSupport32Bit = true; # For 32 bit applications. + + extraPackages = with pkgs; [ + rocmPackages.clr.icd # OpenCL + ]; + }; + }; + + networking = { + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + useDHCP = lib.mkDefault true; + # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; + + # Set the hostname. + hostName = "Shura"; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/Shura/monitors.xml b/hosts/Shura/monitors.xml new file mode 100644 index 0000000..c9752e9 --- /dev/null +++ b/hosts/Shura/monitors.xml @@ -0,0 +1,60 @@ + + + + 0 + 0 + 1 + yes + + + DP-2 + MSI + MSI MAG401QR + EA5H013900434 + + + 3440 + 1440 + 144.000 + + + + + + eDP-2 + BOE + 0x0a9b + 0x00000000 + + + + + + 0 + 0 + 1 + yes + + + DP-1 + MSI + MSI MAG401QR + EA5H013900434 + + + 3440 + 1440 + 144.000 + + + + + + eDP-2 + BOE + 0x0a9b + 0x00000000 + + + + diff --git a/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch b/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch new file mode 100644 index 0000000..5a83bad --- /dev/null +++ b/hosts/Shura/patches/legion_7i-gen7-16IAX7-sound-6.7.3.patch @@ -0,0 +1,32 @@ +diff --git a/sound/pci/hda/cs35l41_hda_property.c b/sound/pci/hda/cs35l41_hda_property.c +index d74cf11eef1e..8a6b484b2184 100644 +--- a/sound/pci/hda/cs35l41_hda_property.c ++++ b/sound/pci/hda/cs35l41_hda_property.c +@@ -95,6 +95,7 @@ static const struct cs35l41_config cs35l41_config_table[] = { + { "10431F12", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, + { "10431F1F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 0, 0, 0 }, + { "10431F62", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, ++ { "17AA386F", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, + { "17AA38B4", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, + { "17AA38B5", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, + { "17AA38B6", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 }, +@@ -431,6 +432,7 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { + { "CSC3551", "10431F12", generic_dsd_config }, + { "CSC3551", "10431F1F", generic_dsd_config }, + { "CSC3551", "10431F62", generic_dsd_config }, ++ { "CSC3551", "17AA386F", generic_dsd_config }, + { "CSC3551", "17AA38B4", generic_dsd_config }, + { "CSC3551", "17AA38B5", generic_dsd_config }, + { "CSC3551", "17AA38B6", generic_dsd_config }, +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 6994c4c5073c..9ebe42f33d27 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -10269,6 +10269,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C), + SND_PCI_QUIRK(0x17aa, 0x38a8, "Y780P AMD VECO dual", ALC287_FIXUP_TAS2781_I2C), ++ SND_PCI_QUIRK(0x17aa, 0x3877, "Legion 7 slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x38b4, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x38b5, "Legion Slim 7 16IRH8", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x38b6, "Legion Slim 7 16APH8", ALC287_FIXUP_CS35L41_I2C_2), diff --git a/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch b/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch new file mode 100644 index 0000000..3b87bcb --- /dev/null +++ b/hosts/Shura/patches/lenovo-7i-gen7-sound-6.2.0-rc3-0.0.5b-002.patch @@ -0,0 +1,134 @@ +diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c +index f7815ee24f83..93d86c5a9d53 100644 +--- a/sound/pci/hda/cs35l41_hda.c ++++ b/sound/pci/hda/cs35l41_hda.c +@@ -1270,6 +1270,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + size_t nval; + int i, ret; + ++ printk("CSC3551: probing %s\n", hid); ++ + adev = acpi_dev_get_first_match_dev(hid, NULL, -1); + if (!adev) { + dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); +@@ -1287,8 +1289,9 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + property = "cirrus,dev-index"; + ret = device_property_count_u32(physdev, property); + if (ret <= 0) { +- ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid); +- goto err_put_physdev; ++ //ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid); ++ //goto err_put_physdev; ++ goto no_acpi_dsd; + } + if (ret > ARRAY_SIZE(values)) { + ret = -EINVAL; +@@ -1383,6 +1386,92 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i + put_device(physdev); + + return ret; ++ ++no_acpi_dsd: ++ /* ++ * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. ++ * And devices created by i2c-multi-instantiate don't have their device struct pointing to ++ * the correct fwnode, so acpi_dev must be used here. ++ * And devm functions expect that the device requesting the resource has the correct ++ * fwnode. ++ */ ++ ++ printk("CSC3551: no_acpi_dsd: %s\n", hid); ++ ++ /* TODO: This is a hack. */ ++ if (strncmp(hid, "CSC3551", 7) == 0) { ++ goto csc3551; ++ } ++ ++ if (strncmp(hid, "CLSA0100", 8) != 0) ++ return -EINVAL; ++ ++ /* check I2C address to assign the index */ ++ cs35l41->index = id == 0x40 ? 0 : 1; ++ cs35l41->hw_cfg.spk_pos = cs35l41->index; ++ cs35l41->channel_index = 0; ++ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); ++ cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; ++ hw_cfg->gpio2.func = CS35L41_GPIO2_INT_OPEN_DRAIN; ++ hw_cfg->gpio2.valid = true; ++ cs35l41->hw_cfg.valid = true; ++ put_device(physdev); ++ ++ return 0; ++ ++ csc3551: ++ ++ printk("CSC3551: id == 0x%x\n", id); ++ ++ // cirrus,dev-index ++ if(id == 0x40) ++ cs35l41->index = 0; ++ else ++ cs35l41->index = 1; ++ ++ cs35l41->channel_index = 0; ++ ++ cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, cs35l41->index, GPIOD_OUT_LOW); ++ ++ printk("CS3551: reset_gpio == 0x%x\n", cs35l41->reset_gpio); ++ ++ // cirrus,speaker-position ++ if(cs35l41->index == 0) ++ hw_cfg->spk_pos = 0; ++ else ++ hw_cfg->spk_pos = 1; ++ ++ // cirrus,gpio1-func ++ hw_cfg->gpio1.func = 1; ++ hw_cfg->gpio1.valid = true; ++ ++ // cirrus,gpio2-func ++ hw_cfg->gpio2.func = 0x02; ++ hw_cfg->gpio2.valid = true; ++ ++ // cirrus,boost-peak-milliamp ++ hw_cfg->bst_ipk = -1; ++ ++ // cirrus,boost-ind-nanohenry ++ hw_cfg->bst_ind = -1; ++ ++ // cirrus,boost-cap-microfarad ++ hw_cfg->bst_cap = -1; ++ ++ cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1); ++ ++ if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) ++ hw_cfg->bst_type = CS35L41_INT_BOOST; ++ else ++ hw_cfg->bst_type = CS35L41_EXT_BOOST; ++ ++ hw_cfg->valid = true; ++ ++ put_device(physdev); ++ ++ printk("CSC3551: Done.\n"); ++ ++ return 0; + } + + int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index e103bb3693c0..8ec2b0f99d8c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -9682,6 +9682,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS), + SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6), + SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN), ++ SND_PCI_QUIRK(0x17aa, 0x3874, "Legion 7 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7 16IAX7", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3803, "Legion 7i slim 16IAH7", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3856, "Yoga Slim 7 Carbon 14ACN6", ALC287_FIXUP_CS35L41_I2C_2), ++ SND_PCI_QUIRK(0x17aa, 0x3877, "Legion 7 slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), + SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), + SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), diff --git a/hosts/common/default.nix b/hosts/common/default.nix new file mode 100644 index 0000000..40a86c9 --- /dev/null +++ b/hosts/common/default.nix @@ -0,0 +1,15 @@ +{ lib, ... }: +let + # Fetch secrets. + # NOTE: This requires access to a private repo. Make sure you generate the build as `aires`, then switch to it as root. + nix-secrets = builtins.fetchGit { + url = "ssh://git@code.8bitbuddhism.com:22222/andre/nix-secrets.git"; + ref = "main"; + rev = "a5b902f720e1e51df0f688b29d449c910468fb28"; + }; +in{ + imports = [ + ../../modules + "${nix-secrets}/default.nix" + ]; +} \ No newline at end of file diff --git a/hosts/default.nix b/hosts/default.nix new file mode 100644 index 0000000..5a61ea7 --- /dev/null +++ b/hosts/default.nix @@ -0,0 +1,8 @@ +{ ... }: { + imports = [ + ./Dimaga + ./Haven + ./Pihole + ./Shura + ]; +} \ No newline at end of file diff --git a/modules/apps/default.nix b/modules/apps/default.nix new file mode 100644 index 0000000..a52f5d9 --- /dev/null +++ b/modules/apps/default.nix @@ -0,0 +1,12 @@ +{ ... }: { + imports = [ + ./development.nix + ./dj.nix + ./gaming.nix + ./hugo.nix + ./media.nix + ./office.nix + ./pandoc.nix + ./recording.nix + ]; +} \ No newline at end of file diff --git a/modules/apps/development.nix b/modules/apps/development.nix new file mode 100644 index 0000000..0381a4b --- /dev/null +++ b/modules/apps/development.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: + +let + cfg = config.host.apps.development; +in +with lib; +{ + options = { + host.apps.development.enable = mkEnableOption (mdDoc "Enables development tools"); + }; + + config = mkIf cfg.enable { + host.ui.flatpak.enable = true; + + services.flatpak.packages = [ + "com.vscodium.codium" + "dev.k8slens.OpenLens" + ]; + }; +} \ No newline at end of file diff --git a/modules/apps/dj.nix b/modules/apps/dj.nix new file mode 100644 index 0000000..434c048 --- /dev/null +++ b/modules/apps/dj.nix @@ -0,0 +1,19 @@ +{ config, lib, ... }: + +let + cfg = config.host.apps.dj; +in +with lib; +{ + options = { + host.apps.dj.enable = mkEnableOption (mdDoc "Enables DJing tools (i.e. Mixxx)"); + }; + + config = mkIf cfg.enable { + host.ui.flatpak.enable = true; + + services.flatpak.packages = [ + "org.mixxx.Mixxx" + ]; + }; +} \ No newline at end of file diff --git a/modules/apps/gaming.nix b/modules/apps/gaming.nix new file mode 100644 index 0000000..17e433d --- /dev/null +++ b/modules/apps/gaming.nix @@ -0,0 +1,20 @@ +{ config, lib, pkgs, ... }: + +# Gaming-related settings +let + cfg = config.host.apps.gaming; +in +with lib; +{ + options = { + host.apps.gaming.enable = mkEnableOption (mdDoc "Enables gaming features"); + }; + + config = mkIf cfg.enable { + services.flatpak.packages = lib.mkIf (config.services.flatpak.enable == true) [ + "gg.minion.Minion" + "com.valvesoftware.Steam" + "org.firestormviewer.FirestormViewer" + ]; + }; +} diff --git a/modules/apps/hugo.nix b/modules/apps/hugo.nix new file mode 100644 index 0000000..c623d56 --- /dev/null +++ b/modules/apps/hugo.nix @@ -0,0 +1,19 @@ +{ pkgs, config, lib, ... }: + +let + cfg = config.host.apps.hugo; +in +with lib; +{ + options = { + host.apps.hugo.enable = mkEnableOption (mdDoc "Enables Hugo and webdev tools"); + }; + + config = mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + hugo + rsync + yarn + ]; + }; +} \ No newline at end of file diff --git a/modules/apps/media.nix b/modules/apps/media.nix new file mode 100644 index 0000000..98ecead --- /dev/null +++ b/modules/apps/media.nix @@ -0,0 +1,28 @@ +{ config, lib, ... }: + +let + cfg = config.host.apps.media; +in +with lib; +{ + options = { + host.apps.media.enable = mkEnableOption (mdDoc "Enables media playback and editing apps"); + }; + + config = mkIf cfg.enable { + host.ui.flatpak.enable = true; + + services.flatpak = { + packages = [ + "com.calibre_ebook.calibre" + "com.github.unrud.VideoDownloader" + "io.github.celluloid_player.Celluloid" + "org.kde.krita" + "org.kde.KStyle.Adwaita//5.15-23.08" # Retrieved from https://docs.flatpak.org/en/latest/desktop-integration.html + "org.kde.KStyle.Adwaita//6.5" + "org.kde.WaylandDecoration.QAdwaitaDecorations//5.15-23.08" # Replaced deprecated QGnomePlatform https://wiki.archlinux.org/title/Uniform_look_for_Qt_and_GTK_applications + "org.kde.WaylandDecoration.QAdwaitaDecorations//6.5" + ]; + }; + }; +} \ No newline at end of file diff --git a/modules/apps/office.nix b/modules/apps/office.nix new file mode 100644 index 0000000..7656ede --- /dev/null +++ b/modules/apps/office.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: + +let + cfg = config.host.apps.office; +in +with lib; +{ + options = { + host.apps.office.enable = mkEnableOption (mdDoc "Enables office and workstation apps"); + }; + + config = mkIf cfg.enable { + host.ui.flatpak.enable = true; + + services.flatpak.packages = [ + "org.libreoffice.LibreOffice" + "us.zoom.Zoom" + ]; + }; +} \ No newline at end of file diff --git a/modules/apps/pandoc.nix b/modules/apps/pandoc.nix new file mode 100644 index 0000000..f695e15 --- /dev/null +++ b/modules/apps/pandoc.nix @@ -0,0 +1,20 @@ +{ pkgs, config, lib, ... }: + +let + cfg = config.host.apps.pandoc; +in +with lib; +{ + options = { + host.apps.pandoc.enable = mkEnableOption (mdDoc "Enables pandoc"); + }; + + config = mkIf cfg.enable { + environment.systemPackages = with pkgs; [ + haskellPackages.pandoc + haskellPackages.pandoc-cli + haskellPackages.pandoc-crossref + texliveSmall + ]; + }; +} \ No newline at end of file diff --git a/modules/apps/recording.nix b/modules/apps/recording.nix new file mode 100644 index 0000000..3d30118 --- /dev/null +++ b/modules/apps/recording.nix @@ -0,0 +1,36 @@ +{ config, lib, ... }: + +let + cfg = config.host.apps.recording; +in +with lib; +{ + options = { + host.apps.recording.enable = mkEnableOption (mdDoc "Enables video editing tools"); + }; + + config = mkIf cfg.enable { + host.ui.flatpak.enable = true; + + services.flatpak = { + packages = [ + "com.obsproject.Studio" + "com.obsproject.Studio.Plugin.DroidCam" + "org.kde.kdenlive" + ]; + }; + + # Add a virtual camera to use with Droidcam + boot = { + extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback.out ]; + kernelModules = [ "v4l2loopback" ]; + # Note on v4l2loopback kernel module parameters: + # exclusive_caps: Skype, Zoom, Teams etc. will only show device when actually streaming. This MUST be set to 1 for Chrome to detect virtual cameras. + # card_label: Name of virtual camera, how it'll show up in Skype, Zoom, Teams + # https://github.com/umlaeute/v4l2loopback + extraModprobeConfig = '' + options v4l2loopback exclusive_caps=1 card_label="Virtual Camera" + ''; + }; + }; +} \ No newline at end of file diff --git a/modules/base/bluetooth.nix b/modules/base/bluetooth.nix new file mode 100644 index 0000000..3795301 --- /dev/null +++ b/modules/base/bluetooth.nix @@ -0,0 +1,60 @@ +{ lib, config, pkgs, ... }: + +let + cfg = config.host.ui.bluetooth; +in +with lib; +{ + + options = { + host.ui.bluetooth = { + enable = mkEnableOption (mdDoc "Enables bluetooth"); + }; + }; + + config = mkIf cfg.enable { + # Set up Bluetooth + hardware.bluetooth = { + enable = true; + powerOnBoot = true; + settings = { + General = { + Enable = "Source,Sink,Media,Socket"; + Experimental = true; + KernelExperimental = true; + }; + }; + }; + + # Add Bluetooth LE audio support + environment.systemPackages = with pkgs; [ + liblc3 + ]; + + # Enable Pipewire codec support - see https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/bluetooth.html + # FIXME: Editing etc packages causes a "permission denied" build error. Not sure of the cause. + /* + environment.etc = lib.mkIf (config.sound.enable == true) { + "wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = '' + bluez_monitor.properties = { + ["bluez5.enable-sbc-xq"] = true, + ["bluez5.enable-msbc"] = true, + ["bluez5.enable-hw-volume"] = true, + ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]", + ["bluez5.auto-connect"] = "[ hfp_hf hsp_hs a2dp_sink ]" + } + ''; + + # Reduce audio latency per https://nixos.wiki/wiki/PipeWire#Low-latency_setup + "pipewire/pipewire.conf.d/92-low-latency.conf".text = '' + context.properties = { + default.clock.rate = 48000 + default.clock.quantum = 32 + default.clock.min-quantum = 32 + default.clock.max-quantum = 32 + } + ''; + }; + */ + }; +} \ No newline at end of file diff --git a/modules/base/bootloader.nix b/modules/base/bootloader.nix new file mode 100644 index 0000000..ce6cef7 --- /dev/null +++ b/modules/base/bootloader.nix @@ -0,0 +1,58 @@ +{ config, lib, ... }: + +# Bootloader +let + cfg = config.host.boot; +in +with lib; +{ + + options = { + host.boot = { + enable = mkOption { + description = "Automatically configures the bootloader. Set to false to configure manually."; + type = types.bool; + default = true; + }; + + secureboot.enable = mkOption { + description = "Enables Secureboot"; + type = types.bool; + default = true; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge[ + (mkIf (cfg.secureboot.enable == true) { + boot = { + # Enable Secure Boot + bootspec.enable = true; + + # Disable systemd-boot. We lanzaboote now. + loader.systemd-boot.enable = false; + loader.efi.canTouchEfiVariables = true; + lanzaboote = { + enable = true; + pkiBundle = "/etc/secureboot"; + }; + }; + + # Set up TPM. See https://nixos.wiki/wiki/TPM + # After installing and rebooting, set it up via https://wiki.archlinux.org/title/Systemd-cryptenroll#Trusted_Platform_Module + security.tpm2 = { + enable = true; + pkcs11.enable = true; + tctiEnvironment.enable = true; + }; + }) + + # Plain boot + (mkIf (cfg.secureboot.enable == false) { + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + }; + }) + ]); +} diff --git a/modules/base/default.nix b/modules/base/default.nix new file mode 100644 index 0000000..fe9ebfd --- /dev/null +++ b/modules/base/default.nix @@ -0,0 +1,9 @@ +{ ... }: { + imports = [ + ./bluetooth.nix + ./bootloader.nix + ./network.nix + ./shell.nix + ./system.nix + ]; +} \ No newline at end of file diff --git a/modules/base/network.nix b/modules/base/network.nix new file mode 100644 index 0000000..ca33112 --- /dev/null +++ b/modules/base/network.nix @@ -0,0 +1,12 @@ +{ ... }: { + networking = { + # Enable networking via NetworkManager + networkmanager.enable = true; + + # Enable firewall + nftables.enable = true; + firewall = { + enable = true; + }; + }; +} \ No newline at end of file diff --git a/modules/base/shell.nix b/modules/base/shell.nix new file mode 100644 index 0000000..97bbdbb --- /dev/null +++ b/modules/base/shell.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + # Install ZSH for all users + programs.zsh.enable = true; + users.defaultUserShell = pkgs.zsh; +} diff --git a/modules/base/system.nix b/modules/base/system.nix new file mode 100644 index 0000000..1c3ab64 --- /dev/null +++ b/modules/base/system.nix @@ -0,0 +1,163 @@ +{ pkgs, config, lib, inputs, ... }: + +# System options +let + cfg = config.host.system; +in +with lib; +{ + config = { + # Set up the environment + environment = { + # Install base packages + systemPackages = with pkgs; [ + bash + dconf # Needed to fix an issue with Home-manager. See https://github.com/nix-community/home-manager/issues/3113 + git + home-manager + nano + p7zip + tpm2-tss + ]; + + # Set default editor to nano + variables.EDITOR = "nano"; + + # System configuration file overrides + etc = { + # Reduce systemd logout time to 30s + "systemd/system.conf.d/10-reduce-logout-wait-time.conf" = { + text = '' + [Manager] + DefaultTimeoutStopSec=30s + ''; + }; + }; + }; + + # Enable automatic updates. I'm using a weird setup here to account for pulling secrets from a private repo, which requires aires' SSH keys. + systemd.services = { + "nixos-rebuild" = { + script = '' + nixos-rebuild build . --flake + ''; + serviceConfig = { + Type = "oneshot"; + User = "${config.users.users.aires.name}"; + WorkingDirectory = "${config.users.users.aires.home}/Development/nix-configuration"; + }; + }; + + "nixos-activate" = { + script = '' + ./result/switch-to-configuration switch + ''; + requires = [ "nixos-rebuild.service" ]; + serviceConfig = { + Type = "oneshot"; + User = "${config.users.users.root.name}"; + WorkingDirectory = "${config.users.users.aires.home}/Development/nix-configuration"; + }; + }; + }; + systemd.timers = { + "nixos-update" = { + wantedBy = [ "timers.target" ]; + wants = [ "network-online.target" ]; + timerConfig = { + Unit = "nixos-activate.service"; + OnCalendar = "daily"; + Persistent = true; + }; + }; + }; + + # Configure automatic updates (deprecated in favor of systemd timers) + /* + system = { + # Enable automatic updates + autoUpgrade = { + enable = true; + flake = "${config.users.users.aires.home}/Development/nix-configuration"; + flags = [ + "--commit-lock-file" # Create a new commit when flake.lock updates + "--update-input" + "nixpkgs" + "-L" # print build logs + ]; + dates = "02:00"; + randomizedDelaySec = "45min"; + allowReboot = false; + }; + }; + */ + + # Set your time zone. + time.timeZone = "America/New_York"; + + # Select internationalisation properties. + i18n = { + defaultLocale = "en_US.UTF-8"; + + extraLocaleSettings = { + LC_ADDRESS = "en_US.UTF-8"; + LC_IDENTIFICATION = "en_US.UTF-8"; + LC_MEASUREMENT = "en_US.UTF-8"; + LC_MONETARY = "en_US.UTF-8"; + LC_NAME = "en_US.UTF-8"; + LC_NUMERIC = "en_US.UTF-8"; + LC_PAPER = "en_US.UTF-8"; + LC_TELEPHONE = "en_US.UTF-8"; + LC_TIME = "en_US.UTF-8"; + }; + }; + + # Configure nix + nix = { + # Enables Flakes + settings.experimental-features = [ "nix-command" "flakes" ]; + + # Enable periodic nix store optimization + optimise.automatic = true; + + # Enable garbage collection + gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 7d"; + }; + + # Configure NixOS to use the same software channel as Flakes + registry = lib.mapAttrs (_: value: { flake = value; }) inputs; + nixPath = lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry; + }; + + # Set up base apps + programs = { + direnv.enable = true; + + nano = { + enable = true; + syntaxHighlight = true; + nanorc = '' + set linenumbers + set tabsize 4 + set softwrap + ''; + }; + }; + + # Scrub BTRFS partitions if the root partition is btrfs + services.btrfs.autoScrub = lib.mkIf (config.fileSystems."/".fsType == "btrfs") { + enable = true; + interval = "weekly"; + fileSystems = [ "/" ]; + }; + + # Enable fwupd (firmware updater) + services.fwupd.enable = true; + + # Allow systemd user services to keep running after the user has logged out + services.logind.killUserProcesses = false; + }; +} diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..2b6463b --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,10 @@ +{ ... }: { + imports = [ + ./apps + ./base + ./roles + ./services + ./ui + ./users + ]; +} \ No newline at end of file diff --git a/modules/packages/duplicacy-web.nix b/modules/packages/duplicacy-web.nix new file mode 100644 index 0000000..5afc500 --- /dev/null +++ b/modules/packages/duplicacy-web.nix @@ -0,0 +1,27 @@ +{ pkgs, lib }: + +pkgs.stdenv.mkDerivation rec { + pname = "duplicacy-web"; + version = "1.7.2"; + + src = builtins.fetchurl { + url = "https://acrosync.com/duplicacy-web/duplicacy_web_linux_x64_${version}"; + sha256 = "88383f7fea8462539cab7757dfa167bf42e37cbc19531b9de97373bc20efd317"; + }; + + doCheck = false; + + dontUnpack = true; + + installPhase = '' + install -D $src $out/duplicacy-web + chmod a+x $out/duplicacy-web + ''; + + meta = with lib; { + homepage = "https://duplicacy.com"; + description = "A new generation cloud backup tool"; + platforms = platforms.linux; + license = licenses.unfreeRedistributable; + }; +} diff --git a/modules/roles/default.nix b/modules/roles/default.nix new file mode 100644 index 0000000..39006e2 --- /dev/null +++ b/modules/roles/default.nix @@ -0,0 +1,18 @@ +{lib, ...}: + +with lib; +{ + imports = [ + ./server.nix + ./workstation.nix + ]; + + options = { + host.role = mkOption { + type = types.enum [ + "server" + "workstation" + ]; + }; + }; +} \ No newline at end of file diff --git a/modules/roles/server.nix b/modules/roles/server.nix new file mode 100644 index 0000000..3c98482 --- /dev/null +++ b/modules/roles/server.nix @@ -0,0 +1,15 @@ +{ config, lib, modulesPath, pkgs, ... }: +let + role = config.host.role; +in + with lib; +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + config = mkIf (role == "server") { + environment.systemPackages = with pkgs; [ + direnv + htop + ]; + }; +} \ No newline at end of file diff --git a/modules/roles/workstation.nix b/modules/roles/workstation.nix new file mode 100644 index 0000000..0c55699 --- /dev/null +++ b/modules/roles/workstation.nix @@ -0,0 +1,35 @@ +{ config, lib, modulesPath, pkgs, ... }: +let + role = config.host.role; +in + with lib; +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + config = mkIf (role == "workstation") { + host.ui = { + audio.enable = true; + bluetooth.enable = true; + gnome.enable = true; + flatpak.enable = true; + }; + + environment.systemPackages = with pkgs; [ + direnv + ]; + + boot = { + # Enable Plymouth + plymouth.enable = true; + plymouth.theme = "bgrt"; + + # Increase minimum log level. This removes ACPI errors from the boot screen. + consoleLogLevel = 1; + + # Add kernel parameters + kernelParams = [ + "quiet" + ]; + }; + }; +} \ No newline at end of file diff --git a/modules/services/apcupsd.nix b/modules/services/apcupsd.nix new file mode 100644 index 0000000..899327a --- /dev/null +++ b/modules/services/apcupsd.nix @@ -0,0 +1,17 @@ +{ pkgs, config, lib, ... }: +let + cfg = config.host.services.apcupsd; +in +with lib; +{ + options = { + host.services.apcupsd.enable = mkEnableOption (mdDoc "Enables apcupsd"); + }; + + config = mkIf cfg.enable { + services.apcupsd = { + enable = true; + configText = (builtins.readFile ./etc/apcupsd.conf); + }; + }; +} \ No newline at end of file diff --git a/modules/services/default.nix b/modules/services/default.nix new file mode 100644 index 0000000..7fb3420 --- /dev/null +++ b/modules/services/default.nix @@ -0,0 +1,8 @@ +{ ... }: { + imports = [ + ./apcupsd.nix + ./duplicacy-web.nix + ./k3s.nix + ./msmtp.nix + ]; +} \ No newline at end of file diff --git a/modules/services/duplicacy-web.nix b/modules/services/duplicacy-web.nix new file mode 100644 index 0000000..187c8e2 --- /dev/null +++ b/modules/services/duplicacy-web.nix @@ -0,0 +1,52 @@ +{ pkgs, config, lib, ... }: + +let + cfg = config.host.services.duplicacy-web; + duplicacy-web = pkgs.callPackage ../packages/duplicacy-web.nix { inherit pkgs lib; }; +in +with lib; +rec { + options = { + host.services.duplicacy-web = { + enable = mkEnableOption (mdDoc "Enables duplicacy-web"); + autostart = mkOption { + default = true; + type = types.bool; + description = "Whether to auto-start duplicacy-web on boot"; + }; + + environment = mkOption { + default = ""; + type = types.str; + description = "Environment where duplicacy-web stores its config files"; + }; + }; + }; + + config = mkIf cfg.enable { + nixpkgs.config.allowUnfree = true; + environment.systemPackages = [ + duplicacy-web + ]; + + networking.firewall.allowedTCPPorts = [ 3875 ]; + + # Install systemd service. + systemd.services."duplicacy-web" = { + enable = true; + wants = [ "network-online.target" ]; + after = [ "syslog.target" "network-online.target" ]; + description = "Start the Duplicacy backup service and web UI"; + serviceConfig = { + Type = "simple"; + ExecStart = ''${duplicacy-web}/duplicacy-web''; + Restart = "on-failure"; + RestartSrc = 10; + KillMode = "process"; + }; + environment = { + HOME = cfg.environment; + }; + } // optionalAttrs (cfg.autostart == true) { wantedBy = ["multi-user.target"]; }; # Start at boot if autostart is enabled. + }; +} diff --git a/modules/services/etc/apcupsd.conf b/modules/services/etc/apcupsd.conf new file mode 100644 index 0000000..fd5b232 --- /dev/null +++ b/modules/services/etc/apcupsd.conf @@ -0,0 +1,333 @@ +## apcupsd.conf v1.1 ## +# +# for apcupsd release 3.14.12 (29 March 2014) - debian +# +# "apcupsd" POSIX config file + +# +# ========= General configuration parameters ============ +# + +# UPSNAME xxx +# Use this to give your UPS a name in log files and such. This +# is particulary useful if you have multiple UPSes. This does not +# set the EEPROM. It should be 8 characters or less. +#UPSNAME + +# UPSCABLE +# Defines the type of cable connecting the UPS to your computer. +# +# Possible generic choices for are: +# simple, smart, ether, usb +# +# Or a specific cable model number may be used: +# 940-0119A, 940-0127A, 940-0128A, 940-0020B, +# 940-0020C, 940-0023A, 940-0024B, 940-0024C, +# 940-1524C, 940-0024G, 940-0095A, 940-0095B, +# 940-0095C, 940-0625A, M-04-02-2000 +# +UPSCABLE usb + +# To get apcupsd to work, in addition to defining the cable +# above, you must also define a UPSTYPE, which corresponds to +# the type of UPS you have (see the Description for more details). +# You must also specify a DEVICE, sometimes referred to as a port. +# For USB UPSes, please leave the DEVICE directive blank. For +# other UPS types, you must specify an appropriate port or address. +# +# UPSTYPE DEVICE Description +# apcsmart /dev/tty** Newer serial character device, appropriate for +# SmartUPS models using a serial cable (not USB). +# +# usb Most new UPSes are USB. A blank DEVICE +# setting enables autodetection, which is +# the best choice for most installations. +# +# net hostname:port Network link to a master apcupsd through apcupsd's +# Network Information Server. This is used if the +# UPS powering your computer is connected to a +# different computer for monitoring. +# +# snmp hostname:port:vendor:community +# SNMP network link to an SNMP-enabled UPS device. +# Hostname is the ip address or hostname of the UPS +# on the network. Vendor can be can be "APC" or +# "APC_NOTRAP". "APC_NOTRAP" will disable SNMP trap +# catching; you usually want "APC". Port is usually +# 161. Community is usually "private". +# +# netsnmp hostname:port:vendor:community +# OBSOLETE +# Same as SNMP above but requires use of the +# net-snmp library. Unless you have a specific need +# for this old driver, you should use 'snmp' instead. +# +# dumb /dev/tty** Old serial character device for use with +# simple-signaling UPSes. +# +# pcnet ipaddr:username:passphrase:port +# PowerChute Network Shutdown protocol which can be +# used as an alternative to SNMP with the AP9617 +# family of smart slot cards. ipaddr is the IP +# address of the UPS management card. username and +# passphrase are the credentials for which the card +# has been configured. port is the port number on +# which to listen for messages from the UPS, normally +# 3052. If this parameter is empty or missing, the +# default of 3052 will be used. +# +# modbus /dev/tty** Serial device for use with newest SmartUPS models +# supporting the MODBUS protocol. +# +UPSTYPE usb +DEVICE + +# POLLTIME +# Interval (in seconds) at which apcupsd polls the UPS for status. This +# setting applies both to directly-attached UPSes (UPSTYPE apcsmart, usb, +# dumb) and networked UPSes (UPSTYPE net, snmp). Lowering this setting +# will improve apcupsd's responsiveness to certain events at the cost of +# higher CPU utilization. The default of 60 is appropriate for most +# situations. +#POLLTIME 60 + +# LOCKFILE +# Path for device lock file. Not used on Win32. +LOCKFILE /var/lock + +# SCRIPTDIR +# Directory in which apccontrol and event scripts are located. +SCRIPTDIR /etc/apcupsd + +# PWRFAILDIR +# Directory in which to write the powerfail flag file. This file +# is created when apcupsd initiates a system shutdown and is +# checked in the OS halt scripts to determine if a killpower +# (turning off UPS output power) is required. +PWRFAILDIR /etc/apcupsd + +# NOLOGINDIR +# Directory in which to write the nologin file. The existence +# of this flag file tells the OS to disallow new logins. +NOLOGINDIR /etc + + +# +# ======== Configuration parameters used during power failures ========== +# + +# The ONBATTERYDELAY is the time in seconds from when a power failure +# is detected until we react to it with an onbattery event. +# +# This means that, apccontrol will be called with the powerout argument +# immediately when a power failure is detected. However, the +# onbattery argument is passed to apccontrol only after the +# ONBATTERYDELAY time. If you don't want to be annoyed by short +# powerfailures, make sure that apccontrol powerout does nothing +# i.e. comment out the wall. +ONBATTERYDELAY 6 + +# +# Note: BATTERYLEVEL, MINUTES, and TIMEOUT work in conjunction, so +# the first that occurs will cause the initation of a shutdown. +# + +# If during a power failure, the remaining battery percentage +# (as reported by the UPS) is below or equal to BATTERYLEVEL, +# apcupsd will initiate a system shutdown. +BATTERYLEVEL 5 + +# If during a power failure, the remaining runtime in minutes +# (as calculated internally by the UPS) is below or equal to MINUTES, +# apcupsd, will initiate a system shutdown. +MINUTES 5 + +# If during a power failure, the UPS has run on batteries for TIMEOUT +# many seconds or longer, apcupsd will initiate a system shutdown. +# A value of 0 disables this timer. +# +# Note, if you have a Smart UPS, you will most likely want to disable +# this timer by setting it to zero. That way, you UPS will continue +# on batteries until either the % charge remaing drops to or below BATTERYLEVEL, +# or the remaining battery runtime drops to or below MINUTES. Of course, +# if you are testing, setting this to 60 causes a quick system shutdown +# if you pull the power plug. +# If you have an older dumb UPS, you will want to set this to less than +# the time you know you can run on batteries. +TIMEOUT 0 + +# Time in seconds between annoying users to signoff prior to +# system shutdown. 0 disables. +ANNOY 300 + +# Initial delay after power failure before warning users to get +# off the system. +ANNOYDELAY 60 + +# The condition which determines when users are prevented from +# logging in during a power failure. +# NOLOGON [ disable | timeout | percent | minutes | always ] +NOLOGON disable + +# If KILLDELAY is non-zero, apcupsd will continue running after a +# shutdown has been requested, and after the specified time in +# seconds attempt to kill the power. This is for use on systems +# where apcupsd cannot regain control after a shutdown. +# KILLDELAY 0 disables +KILLDELAY 0 + +# +# ==== Configuration statements for Network Information Server ==== +# + +# NETSERVER [ on | off ] on enables, off disables the network +# information server. If netstatus is on, a network information +# server process will be started for serving the STATUS and +# EVENT data over the network (used by CGI programs). +NETSERVER on + +# NISIP +# IP address on which NIS server will listen for incoming connections. +# This is useful if your server is multi-homed (has more than one +# network interface and IP address). Default value is 0.0.0.0 which +# means any incoming request will be serviced. Alternatively, you can +# configure this setting to any specific IP address of your server and +# NIS will listen for connections only on that interface. Use the +# loopback address (127.0.0.1) to accept connections only from the +# local machine. +NISIP 127.0.0.1 + +# NISPORT default is 3551 as registered with the IANA +# port to use for sending STATUS and EVENTS data over the network. +# It is not used unless NETSERVER is on. If you change this port, +# you will need to change the corresponding value in the cgi directory +# and rebuild the cgi programs. +NISPORT 3551 + +# If you want the last few EVENTS to be available over the network +# by the network information server, you must define an EVENTSFILE. +EVENTSFILE /var/log/apcupsd.events + +# EVENTSFILEMAX +# By default, the size of the EVENTSFILE will be not be allowed to exceed +# 10 kilobytes. When the file grows beyond this limit, older EVENTS will +# be removed from the beginning of the file (first in first out). The +# parameter EVENTSFILEMAX can be set to a different kilobyte value, or set +# to zero to allow the EVENTSFILE to grow without limit. +EVENTSFILEMAX 10 + +# +# ========== Configuration statements used if sharing ============= +# a UPS with more than one machine + +# +# Remaining items are for ShareUPS (APC expansion card) ONLY +# + +# UPSCLASS [ standalone | shareslave | sharemaster ] +# Normally standalone unless you share an UPS using an APC ShareUPS +# card. +UPSCLASS standalone + +# UPSMODE [ disable | share ] +# Normally disable unless you share an UPS using an APC ShareUPS card. +UPSMODE disable + +# +# ===== Configuration statements to control apcupsd system logging ======== +# + +# Time interval in seconds between writing the STATUS file; 0 disables +STATTIME 0 + +# Location of STATUS file (written to only if STATTIME is non-zero) +STATFILE /var/log/apcupsd.status + +# LOGSTATS [ on | off ] on enables, off disables +# Note! This generates a lot of output, so if +# you turn this on, be sure that the +# file defined in syslog.conf for LOG_NOTICE is a named pipe. +# You probably do not want this on. +LOGSTATS off + +# Time interval in seconds between writing the DATA records to +# the log file. 0 disables. +DATATIME 0 + +# FACILITY defines the logging facility (class) for logging to syslog. +# If not specified, it defaults to "daemon". This is useful +# if you want to separate the data logged by apcupsd from other +# programs. +#FACILITY DAEMON + +# +# ========== Configuration statements used in updating the UPS EPROM ========= +# + +# +# These statements are used only by apctest when choosing "Set EEPROM with conf +# file values" from the EEPROM menu. THESE STATEMENTS HAVE NO EFFECT ON APCUPSD. +# + +# UPS name, max 8 characters +#UPSNAME UPS_IDEN + +# Battery date - 8 characters +#BATTDATE mm/dd/yy +BATTDATE 07/08/19 + +# Sensitivity to line voltage quality (H cause faster transfer to batteries) +# SENSITIVITY H M L (default = H) +#SENSITIVITY H + +# UPS delay after power return (seconds) +# WAKEUP 000 060 180 300 (default = 0) +#WAKEUP 60 + +# UPS Grace period after request to power off (seconds) +# SLEEP 020 180 300 600 (default = 20) +#SLEEP 180 + +# Low line voltage causing transfer to batteries +# The permitted values depend on your model as defined by last letter +# of FIRMWARE or APCMODEL. Some representative values are: +# D 106 103 100 097 +# M 177 172 168 182 +# A 092 090 088 086 +# I 208 204 200 196 (default = 0 => not valid) +#LOTRANSFER 208 + +# High line voltage causing transfer to batteries +# The permitted values depend on your model as defined by last letter +# of FIRMWARE or APCMODEL. Some representative values are: +# D 127 130 133 136 +# M 229 234 239 224 +# A 108 110 112 114 +# I 253 257 261 265 (default = 0 => not valid) +#HITRANSFER 253 + +# Battery charge needed to restore power +# RETURNCHARGE 00 15 50 90 (default = 15) +#RETURNCHARGE 15 + +# Alarm delay +# 0 = zero delay after pwr fail, T = power fail + 30 sec, L = low battery, N = never +# BEEPSTATE 0 T L N (default = 0) +BEEPSTATE N + +# Low battery warning delay in minutes +# LOWBATT 02 05 07 10 (default = 02) +#LOWBATT 2 + +# UPS Output voltage when running on batteries +# The permitted values depend on your model as defined by last letter +# of FIRMWARE or APCMODEL. Some representative values are: +# D 115 +# M 208 +# A 100 +# I 230 240 220 225 (default = 0 => not valid) +#OUTPUTVOLTS 230 + +# Self test interval in hours 336=2 weeks, 168=1 week, ON=at power on +# SELFTEST 336 168 ON OFF (default = 336) +#SELFTEST 336 diff --git a/modules/services/k3s.nix b/modules/services/k3s.nix new file mode 100644 index 0000000..65264c0 --- /dev/null +++ b/modules/services/k3s.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.host.services.k3s; +in +with lib; +{ + options = { + host.services.k3s = { + enable = mkEnableOption (mdDoc "Enables K3s"); + role = mkOption { + default = "server"; + type = types.enum [ + "agent" + "server" + ]; + description = "Which K3s role to use"; + }; + serverAddr = mkOption { + default = ""; + type = types.str; + description = "If an agent, this is the address of the server."; + }; + }; + }; + + config = mkIf cfg.enable { + # Add packages for developing with K3s. + # For details, see https://nixos.wiki/wiki/K3s + environment.systemPackages = with pkgs; [ + k3s + ]; + + networking.firewall = { + allowedTCPPorts = [ + 6443 # k3s: required so that pods can reach the API server (running on port 6443 by default) + # 2379 # k3s, etcd clients: required if using a "High Availability Embedded etcd" configuration + # 2380 # k3s, etcd peers: required if using a "High Availability Embedded etcd" configuration + ]; + allowedUDPPorts = [ + # 8472 # k3s, flannel: required if using multi-node for inter-node networking + ]; + }; + + services.k3s = { + enable = true; + role = cfg.role; + extraFlags = toString [ + # "--kubelet-arg=v=4" # Optionally add additional args to k3s + ]; + } // optionalAttrs (cfg.role == "agent") { serverAddr = cfg.serverAddr; }; + + # Increase number of open file handlers so K3s doesn't exhaust them...again. + systemd.extraConfig = '' + DefaultLimitNOFILE=8192:1048576 + ''; + }; +} \ No newline at end of file diff --git a/modules/services/msmtp.nix b/modules/services/msmtp.nix new file mode 100644 index 0000000..9b3c603 --- /dev/null +++ b/modules/services/msmtp.nix @@ -0,0 +1,25 @@ +# See https://nixos.wiki/wiki/Msmtp +{ config, lib, ... }: + +let + cfg = config.host.services.msmtp; +in +with lib; +{ + options = { + host.services.msmtp.enable = mkEnableOption (mdDoc "Enables mail server"); + }; + + config = mkIf cfg.enable { + programs.msmtp = { + enable = true; + accounts.default = { + auth = true; + tls = true; + from = "root@${config.networking.hostName}"; + user = "root"; + # SMTP host and password set in nix-secrets + }; + }; + }; +} \ No newline at end of file diff --git a/modules/ui/audio.nix b/modules/ui/audio.nix new file mode 100644 index 0000000..20ca0d0 --- /dev/null +++ b/modules/ui/audio.nix @@ -0,0 +1,33 @@ +{ pkgs, lib, config, ... }: + +let + cfg = config.host.ui.audio; +in +with lib; +{ + options = { + host.ui.audio.enable = mkEnableOption (mdDoc "Enables audio"); + }; + + config = mkIf cfg.enable { + # Enable sound with pipewire. + sound.enable = true; + security.rtkit.enable = true; + hardware.pulseaudio = { + enable = false; + package = pkgs.pulseaudioFull; # Enable extra audio codecs + }; + + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; + + services.flatpak.packages = lib.mkIf (config.host.ui.flatpak.enable == true) [ + "com.github.wwmm.easyeffects" + ]; + }; +} \ No newline at end of file diff --git a/modules/ui/default.nix b/modules/ui/default.nix new file mode 100644 index 0000000..7f28c3d --- /dev/null +++ b/modules/ui/default.nix @@ -0,0 +1,9 @@ +{ ... }: + +{ + imports = [ + ./audio.nix + ./flatpak.nix + ./gnome.nix + ]; +} \ No newline at end of file diff --git a/modules/ui/flatpak.nix b/modules/ui/flatpak.nix new file mode 100644 index 0000000..9faa9d1 --- /dev/null +++ b/modules/ui/flatpak.nix @@ -0,0 +1,65 @@ +{ nix-flatpak, pkgs, config, lib, ... }: + +# Flatpak support and options +let + cfg = config.host.ui.flatpak; +in +with lib; +{ + options = { + host.ui.flatpak.enable = mkEnableOption (mdDoc "Enables Flatpak"); + }; + + config = mkIf cfg.enable { + # Enable Flatpak + services.flatpak = { + enable = true; + + # Enable daily automatic updates + update.auto = { + enable = true; + onCalendar = "daily"; + }; + + # Add remote(s) + remotes = [ + { name = "flathub"; location = "https://dl.flathub.org/repo/flathub.flatpakrepo"; } + ]; + + # Install Flatpaks. For details, see https://github.com/gmodena/nix-flatpak + packages = [ + "com.github.tchx84.Flatseal" + "md.obsidian.Obsidian" + "org.keepassxc.KeePassXC" + "org.mozilla.firefox" + ]; + }; + + # Workaround for getting Flatpak apps to use system fonts, icons, and cursors + # For details (and source), see https://github.com/NixOS/nixpkgs/issues/119433#issuecomment-1767513263 + system.fsPackages = [ pkgs.bindfs ]; + fileSystems = let + mkRoSymBind = path: { + device = path; + fsType = "fuse.bindfs"; + options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ]; + }; + aggregatedIcons = pkgs.buildEnv { + name = "system-icons"; + paths = with pkgs; [ + #libsForQt5.breeze-qt5 # for plasma + gnome.gnome-themes-extra + ]; + pathsToLink = [ "/share/icons" ]; + }; + aggregatedFonts = pkgs.buildEnv { + name = "system-fonts"; + paths = config.fonts.packages; + pathsToLink = [ "/share/fonts" ]; + }; + in { + "/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons"; + "/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts"; + }; + }; +} diff --git a/modules/ui/gnome.nix b/modules/ui/gnome.nix new file mode 100644 index 0000000..5160308 --- /dev/null +++ b/modules/ui/gnome.nix @@ -0,0 +1,122 @@ +{ pkgs, config, lib, ... }: + +# UI and desktop-related options +let + cfg = config.host.ui.gnome; +in +with lib; +{ + + options = { + host.ui.gnome.enable = mkEnableOption (mdDoc "Enables Gnome"); + }; + + config = mkIf cfg.enable { + host.ui.audio.enable = true; + host.ui.flatpak.enable = true; + + # Configure the xserver + services.xserver = { + # Enable the X11 windowing system. + enable = true; + + # Configure keymap in X11 + xkb = { + layout = "us"; + variant = ""; + }; + + # Enable Gnome + desktopManager.gnome.enable = true; + displayManager = { + gdm.enable = true; + }; + }; + + # Remove default packages that came with the install + services.xserver.excludePackages = (with pkgs; [ + xterm + ]); + environment.gnome.excludePackages = (with pkgs; [ + gnome-photos + gnome-tour + gnomeExtensions.extension-list + gedit # text editor + ]) ++ (with pkgs.gnome; [ + cheese # webcam tool + gnome-music + gnome-calendar + epiphany # web browser + geary # email reader + evince # document viewer + gnome-characters + totem # video player + tali # poker game + iagno # go game + hitori # sudoku game + atomix # puzzle game + ]); + + # Install additional Gnome packages + environment.systemPackages = with pkgs; [ + # Gnome tweak tools + gnome.gnome-tweaks + # Gnome extensions + gnomeExtensions.appindicator + gnomeExtensions.dash-to-panel + gnomeExtensions.gsconnect + gnomeExtensions.forge + # Themeing + gnome.gnome-themes-extra + qogir-icon-theme + ]; + + # Install Flatpaks + services.flatpak.packages = [ + "com.mattjakeman.ExtensionManager" + "org.bluesabre.MenuLibre" + "org.gnome.baobab" + "org.gnome.Calculator" + "org.gnome.Characters" + "org.gnome.Calendar" + "org.gnome.Evince" + "org.gnome.Evolution" + "org.gnome.FileRoller" + "org.gnome.Firmware" + "org.gnome.gitg" + "org.gnome.Loupe" # Gnome's fancy new image viewer + "org.gnome.Music" + "org.gnome.seahorse.Application" + "org.gnome.TextEditor" + "org.gtk.Gtk3theme.Adwaita-dark" + ]; + + # Disable CUPS - not needed + services.printing.enable = false; + + # Manage fonts + fonts = { + # Install extra fonts + packages = with pkgs; [ + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + liberation_ttf + fira-code + fira-code-symbols + fira + roboto-slab + ]; + + # Enable font dir for use with Flatpak. See https://nixos.wiki/wiki/Fonts#Flatpak_applications_can.27t_find_system_fonts + fontDir.enable = true; + }; + + # Gnome UI integration for KDE apps + qt = { + enable = true; + platformTheme = "gnome"; + style = "adwaita-dark"; + }; + }; +} diff --git a/modules/users/aires/default.nix b/modules/users/aires/default.nix new file mode 100644 index 0000000..14e0457 --- /dev/null +++ b/modules/users/aires/default.nix @@ -0,0 +1,156 @@ +{ pkgs, lib, config, ... }: + +# Define 'aires' +let + cfg = config.host.users.aires; +in +with lib; +{ + options = { + host.users.aires = { + enable = mkEnableOption (mdDoc "Enables aires user account"); + autologin = mkEnableOption (mdDoc "Automatically logs aires in on boot"); + + services.syncthing = { + enable = mkEnableOption (mdDoc "Enables Syncthing"); + enableTray = mkEnableOption (mdDoc "Enables the Syncthing Tray application"); + autostart = mkOption { + default = true; + type = types.bool; + description = "Whether to auto-start Syncthing on boot"; + }; + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + ({ + users.users.aires = { + isNormalUser = true; + description = "Aires"; + uid = 1000; + extraGroups = [ "input" "networkmanager" "plugdev" "tss" "wheel" ]; # tss group has access to TPM devices + + # Allow systemd services to run even while aires is logged out + linger = true; + }; + + # Install aires-specific Flatpaks + services.flatpak.packages = mkIf (config.services.flatpak.enable == true) [ + "com.discordapp.Discord" + "org.telegram.desktop" + ]; + + # Configure home-manager + home-manager.users.aires = { + imports = [ + ../common/gnome.nix + ]; + + # The state version is required and should stay at the version you originally installed. + home.stateVersion = "24.05"; + + # Let home Manager install and manage itself. + programs.home-manager.enable = true; + + # Basic setup + home.username = "aires"; + home.homeDirectory = "/home/aires"; + + # Install extra packages, specifically gnome extensions + home.packages = lib.mkIf (config.host.ui.gnome.enable) [ + pkgs.gnomeExtensions.wallpaper-slideshow + ]; + + # Set up git + programs.git = { + enable = true; + # Username and email set in nix-secrets + extraConfig = { + push.autoSetupRemote = "true"; + }; + }; + + # SSH set up in nix-secrets + + # Set up Zsh + programs.zsh = { + enable = true; + oh-my-zsh = { + enable = true; + plugins = [ + "git" + ]; + theme = "gentoo"; + }; + enableAutosuggestions = true; + syntaxHighlighting.enable = true; + history.ignoreDups = true; # Do not enter command lines into the history list if they are duplicates of the previous event. + prezto = { + git.submoduleIgnore = "untracked"; # Ignore submodules when they are untracked. + }; + shellAliases = { + dry-build = "cd ~/Development/nix-configuration && nix flake update && nixos-rebuild dry-build --flake ."; + update = "cd ~/Development/nix-configuration && nix flake update && sudo nixos-rebuild switch --flake ."; + upgrade = "update"; + protontricks = "flatpak run com.github.Matoking.protontricks"; + please = "sudo"; + }; + }; + + # Gnome settings specific to aires on Shura + dconf.settings = lib.mkIf (config.networking.hostName == "Shura") { + "org/gnome/desktop/interface" = { + # Increase font scaling(if config.networking.hostName == "Haven" then false else true); + text-scaling-factor = 1.2; + + # Dark mode + color-scheme = "prefer-dark"; + }; + }; + }; + }) + + # Autologin aires + (mkIf (cfg.autologin == true) { + services.xserver.displayManager.autoLogin = { + enable = true; + user = "aires"; + }; + systemd.services = { + "getty@tty1".enable = false; + "autovt@tty1".enable = false; + }; + }) + + # Enable Syncthing + (mkIf (cfg.services.syncthing.enable == true) { + users.users.aires.packages = [ + pkgs.syncthing + (mkIf (cfg.services.syncthing.enableTray == true) pkgs.syncthingtray) + ]; + + # Open port 8080 + networking.firewall.allowedTCPPorts = [ + 8080 + ]; + + home-manager.users.aires = { + # Syncthing options + services.syncthing = { + enable = true; + extraOptions = [ + "--gui-address=0.0.0.0:8080" + "--home=${config.users.users.aires.home}/.config/syncthing" + "--no-default-folder" + ]; + }; + + # Override the default Syncthing settings so it doesn't start on boot + systemd.user.services."syncthing" = mkIf (cfg.services.syncthing.autostart == false) { + Install = lib.mkForce {}; + }; + }; + }) + ]); +} diff --git a/modules/users/common/gnome.nix b/modules/users/common/gnome.nix new file mode 100644 index 0000000..0b9434f --- /dev/null +++ b/modules/users/common/gnome.nix @@ -0,0 +1,51 @@ +{ lib, pkgs, osConfig, ... }: { + # Additional Gnome configurations via home-manager. Imported by default by aires and gremlin. + dconf.settings = lib.mkIf (osConfig.host.ui.gnome.enable) { + "org/gnome/mutter" = { + edge-tiling = true; + workspaces-only-on-primary = false; + }; + + "org/gnome/desktop/interface" = { + # Configure fonts + font-name = "Fira Sans Semi-Light 11"; + document-font-name = "Roboto Slab 11"; + monospace-font-name = "Liberation Mono 11"; + titlebar-font = "Fira Sans Semi-Bold 11"; + + # Configure hinting + font-hinting = "slight"; + font-antialiasing = "rgba"; + + # Configure workspace + enable-hot-corners = true; + }; + + # Configure touchpad scroll & tap behavior + "org/gnome/desktop/peripherals/touchpad" = { + disable-while-typing = true; + click-method = "fingers"; + tap-to-click = true; + natural-scroll = true; + two-finger-scrolling-enabled = true; + }; + + # Tweak window management + "org/gnome/desktop/wm/preferences" = { + button-layout = "appmenu:minimize,maximize,close"; + resize-with-right-button = true; + focus-mode = "click"; + }; + + # Make alt-tab switch windows, not applications + "org/gnome/desktop/wm/keybindings" = { + switch-tab = []; + switch-windows = [ "Tab" ]; + switch-windows-backward = [ "Tab" ]; + }; + + "org/gnome/shell" = { + disable-user-extensions = false; + }; + }; +} diff --git a/modules/users/default.nix b/modules/users/default.nix new file mode 100644 index 0000000..d5c710b --- /dev/null +++ b/modules/users/default.nix @@ -0,0 +1,7 @@ +{ ... }: { + imports = [ + ./aires + ./gremlin + ./media + ]; +} \ No newline at end of file diff --git a/modules/users/gremlin/default.nix b/modules/users/gremlin/default.nix new file mode 100644 index 0000000..9b0d31c --- /dev/null +++ b/modules/users/gremlin/default.nix @@ -0,0 +1,125 @@ +{ pkgs, lib, config, ... }: + +# Define 'gremlin' user +let + cfg = config.host.users.gremlin; +in +with lib; +{ + options = { + host.users.gremlin = { + enable = mkEnableOption (mdDoc "Enables gremlin user account"); + + services.syncthing = { + enable = mkEnableOption (mdDoc "Enables Syncthing"); + enableTray = mkEnableOption (mdDoc "Enables the Syncthing Tray application"); + autostart = mkOption { + default = true; + type = types.bool; + description = "Whether to auto-start Syncthing on boot"; + }; + }; + }; + }; + + config = mkMerge [ + (mkIf cfg.enable { + # Add Gremlin account + users.users.gremlin = { + isNormalUser = true; + description = "Gremlin"; + uid = 1001; + extraGroups = [ "networkmanager" "input" ]; + + # Allow systemd services to keep running even while gremlin is logged out + linger = true; + }; + + # Install gremlin-specific flatpaks + services.flatpak.packages = lib.mkIf (config.services.flatpak.enable == true) [ + "com.google.Chrome" + "com.slack.Slack" + ]; + + home-manager.users.gremlin = { + imports = [ + ../common/gnome.nix + ]; + + # The state version is required and should stay at the version you originally installed. + home.stateVersion = "24.05"; + + # Let home Manager install and manage itself. + programs.home-manager.enable = true; + + # Basic setup + home.username = "gremlin"; + home.homeDirectory = "/home/gremlin"; + + # Set up git + programs.git = { + # Name and email set in nix-secrets + enable = true; + extraConfig = { + push.autoSetupRemote = "true"; + }; + }; + + # SSH entries set in nix-secrets + + # Set up Zsh + programs.zsh = { + enable = true; + # Install and source the p10k theme + plugins = [ + { name = "powerlevel10k"; src = pkgs.zsh-powerlevel10k; file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme"; } + { name = "powerlevel10k-config"; src = ./p10k-config; file = "p10k.zsh"; } + ]; + enableAutosuggestions = true; + syntaxHighlighting.enable = true; + history.ignoreDups = true; # Do not enter command lines into the history list if they are duplicates of the previous event. + prezto = { + git.submoduleIgnore = "untracked"; # Ignore submodules when they are untracked. + }; + shellAliases = { + please = "sudo"; + }; + + oh-my-zsh = { + enable = true; + plugins = [ + "git" + ]; + }; + }; + }; + }) + + # Enable Syncthing + (mkIf (cfg.services.syncthing.enable == true) { + users.users.gremlin = { + packages = [ + pkgs.syncthing + (mkIf (cfg.services.syncthing.enableTray == true) pkgs.syncthingtray) + ]; + }; + + home-manager.users.gremlin = { + # Syncthing options + services.syncthing = { + enable = true; + extraOptions = [ + "--gui-address=0.0.0.0:8081" + "--home=${config.users.users.gremlin.home}.config/syncthing" + "--no-default-folder" + ]; + }; + + # Override the default Syncthing settings so it doesn't start on boot + systemd.user.services."syncthing" = mkIf (cfg.services.syncthing.autostart == false) { + Install = lib.mkForce {}; + }; + }; + }) + ]; +} diff --git a/modules/users/gremlin/p10k-config/p10k.zsh b/modules/users/gremlin/p10k-config/p10k.zsh new file mode 100644 index 0000000..d7d0911 --- /dev/null +++ b/modules/users/gremlin/p10k-config/p10k.zsh @@ -0,0 +1,1781 @@ +# Powerlevel10k config +# Generated by Powerlevel10k configuration wizard on 2024-01-22 at 12:09 EST. +# Based on romkatv/powerlevel10k/config/p10k-rainbow.zsh. +# Wizard options: powerline, rainbow, unicode, angled separators, sharp heads, +# flat tails, 2 lines, solid, full frame, lightest-ornaments, sparse, concise, +# instant_prompt=verbose. +# Type `p10k configure` to generate another config. +# +# Config for Powerlevel10k with powerline prompt style with colorful background. +# Type `p10k configure` to generate your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR' + + # Zsh >= 5.1 is required. + [[ $ZSH_VERSION == (5.<1->*|<6->.*) ]] || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + # prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + perlbrew # perl version from perlbrew (https://github.com/gugod/App-perlbrew) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + scalaenv # scala version from scalaenv (https://github.com/scalaenv/scalaenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + # terraform_version # terraform version (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + toolbox # toolbox name (https://github.com/containers/toolbox) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + lf # lf shell (https://github.com/gokcehan/lf) + xplr # xplr shell (https://github.com/sayanarijit/xplr) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + chezmoi_shell # chezmoi shell (https://www.chezmoi.io/) + vi_mode # vi mode (you don't need this if you've enabled prompt_char) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # cpu_arch # CPU architecture + # time # current time + # =========================[ Line #2 ]========================= + newline + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=powerline + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT= + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. You'll probably want to use the same color + # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%244F╭─' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%244F├─' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%244F╰─' + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%244F─╮' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%244F─┤' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%244F─╯' + + # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or + # '─'. The last two make it easier to see the alignment between left and right prompt and to + # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + # for more compact prompt if using this option. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR='─' + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND= + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE + # ornaments defined above. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=244 + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + # Separator between same-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\uE0B1' + # Separator between same-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\uE0B3' + # Separator between different-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' + # Separator between different-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2' + # To remove a separator between two segments, add "_joined" to the second segment name. + # For example: POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(os_icon context_joined) + + # The right end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0' + # The left end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2' + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL='' + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL='' + # Left prompt terminator for lines without any segments. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=232 + typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Transparent background. + typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND= + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # No surrounding whitespace. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE= + + ##################################[ dir: current directory ]################################## + # Current directory background color. + typeset -g POWERLEVEL9K_DIR_BACKGROUND=4 + # Default current directory foreground color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=254 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=250 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=255 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + # + # Optionally, "first" and "last" can be followed by ":" where is an integer. + # This moves the truncation point to the right (positive offset) or to the left (negative offset) + # relative to the marker. Plain "first" and "last" are equivalent to "first:0" and "last:0" + # respectively. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable and non-existent directories. See POWERLEVEL9K_LOCK_ICON + # and POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v3 + + # The default icon shown next to non-writable and non-existent directories when + # POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3. + typeset -g POWERLEVEL9K_LOCK_ICON='∅' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3, non-writable and non-existent directories + # acquire class suffix _NOT_WRITABLE and NON_EXISTENT respectively. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with one + # of the following classes depending on its writability and existence: WORK, WORK_NOT_WRITABLE or + # WORK_NON_EXISTENT. + # + # Simply assigning classes to directories doesn't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=255 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=255 + # + # # Styling for WORK_NON_EXISTENT. + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_ANCHOR_FOREGROUND=255 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='in ' + + #####################################[ vcs: git status ]###################################### + # Version control background colors. + typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=2 + typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=3 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=2 + typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=3 + typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=8 + + # Branch icon. Set this parameter to '\UE0A0 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master wip ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + # Styling for different parts of Git status. + local meta='%7F' # white foreground + local clean='%0F' # black foreground + local modified='%0F' # black foreground + local untracked='%0F' # black foreground + local conflicted='%1F' # red foreground + + local res + + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + local branch=${(V)VCS_STATUS_LOCAL_BRANCH} + # If local branch name is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#branch > 32 )) && branch[13,-13]="…" # <-- this line + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}" + fi + + if [[ -n $VCS_STATUS_TAG + # Show tag only if not on a branch. + # Tip: To always show tag, delete the next line. + && -z $VCS_STATUS_LOCAL_BRANCH # <-- this line + ]]; then + local tag=${(V)VCS_STATUS_TAG} + # If tag name is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show tag name in full without truncation, delete the next line. + (( $#tag > 32 )) && tag[13,-13]="…" # <-- this line + res+="${meta}#${clean}${tag//\%/%%}" + fi + + # Display the current Git commit if there is no branch and no tag. + # Tip: To always display the current Git commit, delete the next line. + [[ -z $VCS_STATUS_LOCAL_BRANCH && -z $VCS_STATUS_TAG ]] && # <-- this line + res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" + fi + + # Display "wip" if the latest commit's summary contains "wip" or "WIP". + if [[ $VCS_STATUS_COMMIT_SUMMARY == (|*[^[:alnum:]])(wip|WIP)(|[^[:alnum:]]*) ]]; then + res+=" ${modified}wip" + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Custom icon. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='on ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg repository. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=true + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_BACKGROUND=0 + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_BACKGROUND=0 + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=true + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_BACKGROUND=1 + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_BACKGROUND=1 + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=3 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_BACKGROUND=1 + + ###################[ command_execution_time: duration of the last command ]################### + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_BACKGROUND=3 + # Show duration of the last command if takes at least this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='took ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=6 + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND=0 + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Custom icon. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='≡' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=3 + typeset -g POWERLEVEL9K_DIRENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + # Tip: Override these parameters for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND and + # POWERLEVEL9K_ASDF_${TOOL}_BACKGROUND. + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_BACKGROUND=7 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent directory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUBY_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PYTHON_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_GOLANG_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_NODEJS_BACKGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUST_BACKGROUND=208 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_FLUTTER_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_LUA_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=1 + typeset -g POWERLEVEL9K_ASDF_JAVA_BACKGROUND=7 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PERL_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ERLANG_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ELIXIR_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_POSTGRES_BACKGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PHP_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_HASKELL_BACKGROUND=3 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Julia version from asdf. + typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_JULIA_BACKGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_JULIA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JULIA_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=7 + typeset -g POWERLEVEL9K_NORDVPN_BACKGROUND=4 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='nord' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3 + typeset -g POWERLEVEL9K_RANGER_BACKGROUND=0 + # Custom icon. + typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='▲' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=0 + typeset -g POWERLEVEL9K_NNN_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ lf: lf shell (https://github.com/gokcehan/lf) ]####################### + # lf shell color. + typeset -g POWERLEVEL9K_LF_FOREGROUND=0 + typeset -g POWERLEVEL9K_LF_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_LF_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################[ xplr: xplr shell (https://github.com/sayanarijit/xplr) ]################## + # xplr shell color. + typeset -g POWERLEVEL9K_XPLR_FOREGROUND=0 + typeset -g POWERLEVEL9K_XPLR_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_XPLR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_VIM_SHELL_BACKGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=3 + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_NIX_SHELL_BACKGROUND=4 + + # Display the icon of nix_shell if PATH contains a subdirectory of /nix/store. + # typeset -g POWERLEVEL9K_NIX_SHELL_INFER_FROM_PATH=false + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################[ chezmoi_shell: chezmoi shell (https://www.chezmoi.io/) ]################## + # chezmoi shell color. + typeset -g POWERLEVEL9K_CHEZMOI_SHELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_CHEZMOI_SHELL_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_CHEZMOI_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=3 + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_BACKGROUND=0 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=0 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_BACKGROUND=3 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=7 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_BACKGROUND=1 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]########### + # Foreground color. + typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0 + # Text and color for normal (a.k.a. command) vi mode. + typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL + typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2 + # Text and color for visual vi mode. + typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL + typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4 + # Text and color for overtype (a.k.a. overwrite and replace) vi mode. + typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE + typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3 + # Text and color for insert vi mode. + typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING= + typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8 + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=0 + typeset -g POWERLEVEL9K_RAM_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=0 + typeset -g POWERLEVEL9K_SWAP_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_NORMAL_BACKGROUND=2 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_WARNING_BACKGROUND=3 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=0 + typeset -g POWERLEVEL9K_LOAD_CRITICAL_BACKGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=0 + typeset -g POWERLEVEL9K_TODO_BACKGROUND=8 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=255 + typeset -g POWERLEVEL9K_TIMEWARRIOR_BACKGROUND=8 + + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=0 + typeset -g POWERLEVEL9K_TASKWARRIOR_BACKGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ cpu_arch: CPU architecture ]################################ + # CPU architecture color. + typeset -g POWERLEVEL9K_CPU_ARCH_FOREGROUND=0 + typeset -g POWERLEVEL9K_CPU_ARCH_BACKGROUND=3 + + # Hide the segment when on a specific CPU architecture. + # typeset -g POWERLEVEL9K_CPU_ARCH_X86_64_CONTENT_EXPANSION= + # typeset -g POWERLEVEL9K_CPU_ARCH_X86_64_VISUAL_IDENTIFIER_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CPU_ARCH_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 + typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_BACKGROUND=0 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0 + + # Context format when running with privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='with ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_VIRTUALENV_BACKGROUND=4 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # If set to "false", won't show virtualenv if pyenv is already shown. + # If set to "if-different", won't show virtualenv if it's the same as pyenv. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ANACONDA_BACKGROUND=4 + + # Anaconda segment format. The following parameters are available within the expansion. + # + # - CONDA_PREFIX Absolute path to the active Anaconda/Miniconda environment. + # - CONDA_DEFAULT_ENV Name of the active Anaconda/Miniconda environment. + # - CONDA_PROMPT_MODIFIER Configurable prompt modifier (see below). + # - P9K_ANACONDA_PYTHON_VERSION Current python version (python --version). + # + # CONDA_PROMPT_MODIFIER can be configured with the following command: + # + # conda config --set env_prompt '({default_env}) ' + # + # The last argument is a Python format string that can use the following variables: + # + # - prefix The same as CONDA_PREFIX. + # - default_env The same as CONDA_DEFAULT_ENV. + # - name The last segment of CONDA_PREFIX. + # - stacked_env Comma-separated list of names in the environment stack. The first element is + # always the same as default_env. + # + # Note: '({default_env}) ' is the default value of env_prompt. + # + # The default value of POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION expands to $CONDA_PROMPT_MODIFIER + # without the surrounding parentheses, or to the last path component of CONDA_PREFIX if the former + # is empty. + typeset -g POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION='${${${${CONDA_PROMPT_MODIFIER#\(}% }%\)}:-${CONDA_PREFIX:t}}' + + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + typeset -g POWERLEVEL9K_PYENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PYENV_BACKGROUND=4 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display just "$P9K_CONTENT" if it's equal to "$P9K_PYENV_PYTHON_VERSION" or + # starts with "$P9K_PYENV_PYTHON_VERSION/". + # 2. Otherwise display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_CONTENT:#$P9K_PYENV_PYTHON_VERSION(|/*)}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + typeset -g POWERLEVEL9K_GOENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_GOENV_BACKGROUND=4 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_NODENV_BACKGROUND=0 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_NVM_BACKGROUND=5 + # If set to false, hide node version if it's the same as default: + # $(nvm version current) == $(nvm version default). + typeset -g POWERLEVEL9K_NVM_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NVM_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_NODEENV_BACKGROUND=0 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=7 + typeset -g POWERLEVEL9K_NODE_VERSION_BACKGROUND=2 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=255 + typeset -g POWERLEVEL9K_GO_VERSION_BACKGROUND=2 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=0 + typeset -g POWERLEVEL9K_RUST_VERSION_BACKGROUND=208 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=7 + typeset -g POWERLEVEL9K_DOTNET_VERSION_BACKGROUND=5 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=0 + typeset -g POWERLEVEL9K_PHP_VERSION_BACKGROUND=5 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_LARAVEL_VERSION_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_RBENV_BACKGROUND=1 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_JAVA_VERSION_BACKGROUND=7 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=0 + typeset -g POWERLEVEL9K_PACKAGE_BACKGROUND=6 + + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_RVM_BACKGROUND=240 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=0 + typeset -g POWERLEVEL9K_FVM_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_LUAENV_BACKGROUND=4 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=1 + typeset -g POWERLEVEL9K_JENV_BACKGROUND=7 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PLENV_BACKGROUND=4 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ perlbrew: perl version from perlbrew (https://github.com/gugod/App-perlbrew) ]############ + # Perlbrew color. + typeset -g POWERLEVEL9K_PERLBREW_FOREGROUND=67 + # Show perlbrew version only when in a perl project subdirectory. + typeset -g POWERLEVEL9K_PERLBREW_PROJECT_ONLY=true + # Don't show "perl-" at the front. + typeset -g POWERLEVEL9K_PERLBREW_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_PERLBREW_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_PHPENV_BACKGROUND=5 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide PHP version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######[ scalaenv: scala version from scalaenv (https://github.com/scalaenv/scalaenv) ]####### + # Scala color. + typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND=0 + typeset -g POWERLEVEL9K_SCALAENV_BACKGROUND=1 + # Hide scala version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_SCALAENV_SOURCES=(shell local global) + # If set to false, hide scala version if it's the same as global: + # $(scalaenv version-name) == $(scalaenv global). + typeset -g POWERLEVEL9K_SCALAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide scala version if it's equal to "system". + typeset -g POWERLEVEL9K_SCALAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_SCALAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=0 + typeset -g POWERLEVEL9K_HASKELL_STACK_BACKGROUND=3 + + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # Don't show terraform workspace if it's literally "default". + typeset -g POWERLEVEL9K_TERRAFORM_SHOW_DEFAULT=false + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' OTHER) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_BACKGROUND=0 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' OTHER) + typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=4 + typeset -g POWERLEVEL9K_TERRAFORM_OTHER_BACKGROUND=0 + # typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ terraform_version: terraform version (https://www.terraform.io) ]############## + # Terraform version color. + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_FOREGROUND=4 + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_TERRAFORM_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform_version: It shows active terraform version (https://www.terraform.io) ]################# + typeset -g POWERLEVEL9K_TERRAFORM_VERSION_SHOW_ON_COMMAND='terraform|tf' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile|flux|fluxctl|stern|kubeseal|skaffold|kubent|kubecolor|cmctl|sparkctl' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=0 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_BACKGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='○' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='at ' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi|terragrunt' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_AWS_DEFAULT_BACKGROUND=1 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # AWS segment format. The following parameters are available within the expansion. + # + # - P9K_AWS_PROFILE The name of the current AWS profile. + # - P9K_AWS_REGION The region associated with the current AWS profile. + typeset -g POWERLEVEL9K_AWS_CONTENT_EXPANSION='${P9K_AWS_PROFILE//\%/%%}${P9K_AWS_REGION:+ ${P9K_AWS_REGION//\%/%%}}' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2 + typeset -g POWERLEVEL9K_AWS_EB_ENV_BACKGROUND=0 + # Custom icon. + typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='eb' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi|terragrunt' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=7 + typeset -g POWERLEVEL9K_AZURE_BACKGROUND=4 + # Custom icon. + typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='az' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs|gsutil' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=7 + typeset -g POWERLEVEL9K_GCLOUD_BACKGROUND=4 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi|terragrunt' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_BACKGROUND=4 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ##############[ toolbox: toolbox name (https://github.com/containers/toolbox) ]############### + # Toolbox color. + typeset -g POWERLEVEL9K_TOOLBOX_FOREGROUND=0 + typeset -g POWERLEVEL9K_TOOLBOX_BACKGROUND=3 + # Don't display the name of the toolbox if it matches fedora-toolbox-*. + typeset -g POWERLEVEL9K_TOOLBOX_CONTENT_EXPANSION='${P9K_TOOLBOX_NAME:#fedora-toolbox-*}' + # Custom icon. + # typeset -g POWERLEVEL9K_TOOLBOX_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TOOLBOX_PREFIX='in ' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=7 + typeset -g POWERLEVEL9K_PUBLIC_IP_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=0 + typeset -g POWERLEVEL9K_VPN_IP_BACKGROUND=6 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(gpd|wg|(.*tun)|tailscale)[0-9]*|(zt.*)' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_BACKGROUND=4 + typeset -g POWERLEVEL9K_IP_FOREGROUND=0 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+------------------------------------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_BYTES_DELTA | number of bytes received since last prompt + # P9K_IP_TX_BYTES_DELTA | number of bytes sent since last prompt + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+⇡$P9K_IP_TX_RATE }$P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='[ew].*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4 + typeset -g POWERLEVEL9K_PROXY_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + typeset -g POWERLEVEL9K_BATTERY_BACKGROUND=0 + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=0 + typeset -g POWERLEVEL9K_WIFI_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(0 0 0 0 0) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"; empty if unknown + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + + ####################################[ time: current time ]#################################### + # Current time color. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_TIME_BACKGROUND=7 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='at ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and yellow text on red background + # greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -b 1 -f 3 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=3 + typeset -g POWERLEVEL9K_EXAMPLE_BACKGROUND=1 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/modules/users/media/default.nix b/modules/users/media/default.nix new file mode 100644 index 0000000..b11a84e --- /dev/null +++ b/modules/users/media/default.nix @@ -0,0 +1,29 @@ +{ pkgs, lib, config, ... }: + +# Define user for managing media on Haven +let + cfg = config.host.users.media; +in +with lib; +{ + + options = { + host.users.media = { + enable = mkEnableOption (mdDoc "Enables media user account"); + }; + }; + + config = mkIf cfg.enable { + users.groups."media" = { + gid = 1001; + }; + + users.users.media = { + isNormalUser = false; + isSystemUser = true; + description = "Media manager"; + uid = 1001; + group = "media"; + }; + }; +} \ No newline at end of file