diff --git a/.gitignore b/.gitignore index 22a3bf8..df8b0ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ .session -modules/chataigne/squashfs-root +/nixos.qcow2 +/result +/HACKSTATION.qcow2 +/result-man +.gitsecret/keys/random_seed +!*.secret +modules/features/gotify-desktop/gotify-key diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e9c481a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "modules/features/nvim/config"] + path = modules/features/nvim/config + url = https://git.voidarc.co.uk/voidarc/nvim diff --git a/.gitsecret/keys/pubring.kbx b/.gitsecret/keys/pubring.kbx new file mode 100644 index 0000000..aea4e94 Binary files /dev/null and b/.gitsecret/keys/pubring.kbx differ diff --git a/.gitsecret/keys/pubring.kbx~ b/.gitsecret/keys/pubring.kbx~ new file mode 100644 index 0000000..f6698c3 Binary files /dev/null and b/.gitsecret/keys/pubring.kbx~ differ diff --git a/.gitsecret/keys/trustdb.gpg b/.gitsecret/keys/trustdb.gpg new file mode 100644 index 0000000..bbf1b13 Binary files /dev/null and b/.gitsecret/keys/trustdb.gpg differ diff --git a/.gitsecret/paths/mapping.cfg b/.gitsecret/paths/mapping.cfg new file mode 100644 index 0000000..f5ee8a2 --- /dev/null +++ b/.gitsecret/paths/mapping.cfg @@ -0,0 +1 @@ +modules/features/gotify-desktop/gotify-key:f6129ad401b60d5a491d582169088600bb58a537d232b93c22923aede129d5cc diff --git a/README.md b/README.md new file mode 100644 index 0000000..2339870 --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +# The Void +*An opinionated dendritic nix configuration* + +## The Concept + +I have been trying to get consistent, across device experiences from the second that I +started using linux. I tried my best with arch, but I foolishly believed that just remembering +what packages I installed would be enough. Then I started managing my dotfiles with GNU stow, +but that only allowed for a single host per repo. I moved over to doot, and simultaneously nixos. + +I believed a dotfiles manager was my endgame. The final evolution, but it was far from ideal. I had to +manage a mess of dotfiles, submodules and nix packages that were completely uncoupled from the apps that +used them. Hyprland just assumed that I had all of my apps installed, assumed that otter-launcher's +config existed. Just by forgetting an app or a toml file, I had the potential to brick my entire setup. + +This is no longer the case. + +The solution is similar to that of safely typed languages, like rust. Rust, instead of having optional parameters +like typescript, requires that a variable be passed to a function, regardless of whether it contains anything. +This leads to what is essentially a fixed dependancy tree, where there are no points of failiure, only allowing +for logic errors and such. The same methodology can be applied to nix, using flake parts and wrapper scripts. + +Instead of defining the packages beside the app, and its config, you can use the config to define the required binaries. +By wrapping a config that contains a nix variable, ie a binary, that binary is intrinsically linked to that config, +and will therefore always be installed. No more dependancy issues, and because the configs are defined within nix too, no +more potential for missing config files. Dotfile managers are no more, long live dotfile managers. Any app with a `--config` +flag can now be fully versioned and self contained within one repo, config and all, accessible on any machine with nix. + +One command for a truly reproducible, fully contained, configured system. This is the endgame. + +## Usage + +Usage is similar to any other flake, with everything in the module directory being an output. + +The folder structure is simply defined: +``` +modules/ +|- features/ - all available apps, every subfolder contains a seperate wrapped binary +|- attrs/ - attributes composed of other modules, no new features defined +|- system/ - basic system modules, no binaries. Should not be run standalone. (Think network and audio config) +|- hosts/ - available presets for machines. Output names match subfolder names, eg #HACKSTATION, and hostnames +``` + +### Nixos Configurations + +Due to the host module referencing `/etc/nixos/hardware-configuration.nix`, so that it is seperated from the repo, +all rebuild commands will need `--impure`, unless you copy your configuration into the repo. + +HACKSTATION is the heavier system, mobile02 is minimal and has no specialist hyprland config. + +It is recommended to clone the repo beforehand, but the system can be built directly from remote +```bash +# Local Clone, . is the directory containing flake.nix +sudo nixos-rebuild switch --impure --flake . + +# Build from remote +sudo nixos-rebuild switch --impure --flake "git+https://git.voidarc.co.uk/voidarc/nixos.git?ref=dendritic" +``` +Both of these commands can be appended with a desired hostname in order to build that configuration. +```bash +# Example of building mobile02 from a local repo +sudo nixos-rebuild switch --impure --flake .#mobile02 +``` +There is no default output, so if the current hostname doesn't match a host, you will get an error. +Building this config should be non destructive to any existing dotfiles, but will remove all users (not home directories) +from the system other than `user01`, who's default password is `qwer`. + +### Binaries + +Any binary can be run with the same base command (will change when merged to main) +```bash +nix run "git+https://git.voidarc.co.uk/voidarc/nixos.git?ref=dendritic#appname" +``` +`Appname` can be substituted for the name of any folder in the `modules/features` dir, ie `kitty` or `otter-launcher` diff --git a/configs/configuration-laptop.nix b/configs/configuration-laptop.nix deleted file mode 100644 index 72fe0c3..0000000 --- a/configs/configuration-laptop.nix +++ /dev/null @@ -1,49 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: { - networking.hostName = "mobile02"; # Define your hostname. - - # Opengl and vulkan - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ - intel-vaapi-driver - libva-vdpau-driver - ]; - }; - - services.displayManager.sddm = { - enable = true; - theme = "catppuccin-mocha-mauve"; - package = pkgs.kdePackages.sddm; - }; - - environment.systemPackages = with pkgs; [ - # Catppuccin sddm theme - (pkgs.catppuccin-sddm.override { - flavor = "mocha"; - font = "Fira Mono Nerd Font"; - fontSize = "11"; - background = null; - }) - ]; - - # Local User - users.users.user01 = { - extraGroups = []; - packages = with pkgs; [ - # Ricing - inputs.way-edges.packages.${stdenv.hostPlatform.system}.way-edges - inputs.chataigne.packages.${stdenv.hostPlatform.system}.default - - # Terminal - # Apps - ]; - }; - - programs.steam.enable = true; -} diff --git a/configs/configuration-pc.nix b/configs/configuration-pc.nix deleted file mode 100644 index fded34b..0000000 --- a/configs/configuration-pc.nix +++ /dev/null @@ -1,190 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: { - networking.hostName = "HACKSTATION"; - - # Enable nix-ld to run unpatched binaries - programs.nix-ld.enable = true; - programs.nix-ld.libraries = with pkgs; [ - stdenv.cc.cc - zlib - libusb1 - ]; - - # Add Samsung USB udev rules - services.udev.extraRules = '' - SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0666", GROUP="plugdev" - ''; - - hardware.amdgpu.initrd.enable = true; - - # Opengl and vulkan - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ - libva-vdpau-driver - libvdpau-va-gl - rocmPackages.clr.icd - ]; - enable32Bit = true; - }; - - # For rOCM - systemd.tmpfiles.rules = [ - "L+ /opt/rocm - - - - ${pkgs.rocmPackages.clr}" - ]; - - hardware.amdgpu.opencl.enable = true; - - boot.kernelParams = [ - "amdgpu.ppfeaturemask=0xffffffff" - ]; - - # Wake on Lan - networking.interfaces.enp5s0.wakeOnLan.enable = true; - networking.firewall.enable = false; - - systemd.services.NetworkManager-wait-online.enable = false; - - services.displayManager = { - autoLogin.enable = true; - autoLogin.user = "user01"; - sddm = { - enable = true; - }; - }; - - # Pipewire stuff - services.pipewire.extraConfig.pipewire."97-null-sink" = { - "context.objects" = [ - { - factory = "adapter"; - args = { - "factory.name" = "support.null-audio-sink"; - "node.name" = "Null-Sink"; - "node.description" = "Null Sink"; - "media.class" = "Audio/Sink"; - "audio.position" = "FL,FR"; - }; - } - { - factory = "adapter"; - args = { - "factory.name" = "support.null-audio-sink"; - "node.name" = "Null-Source"; - "node.description" = "Null Source"; - "media.class" = "Audio/Source"; - "audio.position" = "FL,FR"; - }; - } - ]; - }; - services.pipewire.extraConfig.pipewire."98-virtual-mic" = { - "context.modules" = [ - { - name = "libpipewire-module-loopback"; - args = { - "audio.position" = "FL,FR"; - "node.description" = "Mumble as Microphone"; - "capture.props" = { - # Mumble's output node name. - "node.target" = "Mumble"; - "node.passive" = true; - }; - "playback.props" = { - "node.name" = "Virtual-Mumble-Microphone"; - "media.class" = "Audio/Source"; - }; - }; - } - ]; - }; - - # Mumble server - services.murmur = { - enable = true; - bandwidth = 540000; - bonjour = true; - password = "mumblepass"; - autobanTime = 0; - }; - - # Local User - users.users.user01 = { - extraGroups = [ - "docker" - "input" - "udev" - "wheel" - ]; - packages = with pkgs; [ - bottles - mumble - gajim - ferdium - delfin - docker - orca-slicer - ffmpeg - inputs.norgolith.packages.${pkgs.stdenv.hostPlatform.system}.default - inputs.cracked-davinci.packages.${pkgs.stdenv.hostPlatform.system}.default - inputs.woomer.packages.${pkgs.stdenv.hostPlatform.system}.default - - # wine - wineWow64Packages.stable - winetricks - wine - wine64 - freetype - ]; - }; - - environment.systemPackages = [ - inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.wrapped - ]; - - programs.obs-studio = { - enable = true; - }; - - programs.wshowkeys = { - enable = true; - package = inputs.wshowkeys.packages.${pkgs.stdenv.hostPlatform.system}.default; - }; - - programs.steam = { - enable = true; - protontricks.enable = true; - extraCompatPackages = with pkgs; [ - proton-ge-bin - ]; - package = pkgs.steam.override { - extraEnv = { - LD_AUDIT = "${ - inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.sls-steam - }/library-inject.so:${ - inputs.sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.sls-steam - }/SLSsteam.so"; - }; - }; - }; - - services.unbound = { - enable = true; - }; - - services.wivrn = { - enable = true; - package = pkgs.unstable.wivrn; - openFirewall = true; - }; - - virtualisation.docker = { - enable = true; - enableOnBoot = false; - }; -} diff --git a/flake.nix b/flake.nix index 46aaa7e..64c94e0 100644 --- a/flake.nix +++ b/flake.nix @@ -4,86 +4,45 @@ inputs = { # System nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05"; - nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; - nvim-wrapped.url = "git+file:///home/user01/.dotfiles/.config/nvim"; - hyprland.url = "github:hyprwm/Hyprland"; # Apps - sls-steam.url = "github:AceSLS/SLSsteam"; - woomer = { - url = "github:voidarclabs/woomer"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - chataigne.url = "./modules/chataigne"; - norgolith = { - url = "github:NTBBloodbath/norgolith"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - wshowkeys = { - url = "github:voidarclabs/wshowkeys"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - # Utils - doot = { - url = "github:voidarclabs/nixos.doot"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - way-edges = { - url = "github:way-edges/way-edges"; - inputs.nixpkgs.follows = "nixpkgs"; + nvim.url = "git+https://git.voidarc.co.uk/voidarc/nvim"; + hyprland = { + url = "git+https://git.voidarc.co.uk/voidarc/hypr"; }; otter-launcher = { url = "github:kuokuo123/otter-launcher"; inputs.nixpkgs.follows = "nixpkgs"; }; - fsel = { - url = "github:Mjoyufull/fsel"; + gotify-desktop = { + url = "github:voidarclabs/gotify-desktop"; inputs.nixpkgs.follows = "nixpkgs"; }; - - # Davinci-resolve - cracked-davinci.url = "git+https://git.voidarc.co.uk/voidarc/nixos.davinci"; - + sls-steam.url = "github:AceSLS/SLSsteam"; + davinci.url = "git+https://git.voidarc.co.uk/voidarc/nixos.davinci"; + quickshell = { + url = "git+https://git.voidarc.co.uk/voidarc/quickshell"; + flake = false; + }; omnisearch = { url = "git+https://git.voidarc.co.uk/voidarc/omnisearch"; inputs.nixpkgs.follows = "nixpkgs"; }; - }; - - outputs = { - self, - nixpkgs, - ... - } @ inputs: let - system = "x86_64-linux"; - - hardwareConfig = import /etc/nixos/hardware-configuration.nix; - common = import ./configs/common.nix; - - mkSystem = extraModules: - nixpkgs.lib.nixosSystem { - inherit system; - specialArgs = {inherit inputs;}; - modules = - [ - common - hardwareConfig - ] - ++ extraModules; - }; - in { - nixosConfigurations = { - mobile02 = mkSystem [./configs/configuration-laptop.nix]; - hackstation = mkSystem [ - ./configs/configuration-pc.nix - # ./modules/davinci/davinci.nix - ./modules/i3/i3.nix - inputs.omnisearch.nixosModules.default - { - services.omnisearch.enable = true; - } - ]; + woomer = { + url = "github:coffeeispower/woomer"; + inputs.nixpkgs.follows = "nixpkgs"; }; + wshowkeys.url = "github:voidarclabs/wshowkeys"; + weylus = { + url = "github:voidarclabs/WeylusCommunityEdition"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Flake parts + flake-parts.url = "github:hercules-ci/flake-parts"; + import-tree.url = "github:vic/import-tree"; + wrappers.url = "github:BirdeeHub/nix-wrapper-modules"; }; + + outputs = inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} (inputs.import-tree ./modules); } diff --git a/modules/attrs/bottles/default.nix b/modules/attrs/bottles/default.nix new file mode 100644 index 0000000..a060228 --- /dev/null +++ b/modules/attrs/bottles/default.nix @@ -0,0 +1,18 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.bottles = moduleWithSystem ({pkgs, ...}: { + environment.systemPackages = with pkgs; [ + (bottles.override { + removeWarningPopup = true; + }) + wineWow64Packages.stable + winetricks + wine + wine64 + freetype + ]; + }); +} diff --git a/modules/attrs/development/default.nix b/modules/attrs/development/default.nix new file mode 100644 index 0000000..ebda1e5 --- /dev/null +++ b/modules/attrs/development/default.nix @@ -0,0 +1,19 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.development = moduleWithSystem ({pkgs, ...}: let + modules = with self.nixosModules; [ + git + nvim + ]; + in { + imports = modules; + environment.systemPackages = with pkgs; [ + opencode + devenv + jellyfin-tui + ]; + }); +} diff --git a/modules/attrs/gaming/default.nix b/modules/attrs/gaming/default.nix new file mode 100644 index 0000000..437e566 --- /dev/null +++ b/modules/attrs/gaming/default.nix @@ -0,0 +1,13 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.gaming = moduleWithSystem ({...}: let + modules = with self.nixosModules; [ + steam + ]; + in { + imports = modules; + }); +} diff --git a/modules/attrs/youtube/default.nix b/modules/attrs/youtube/default.nix new file mode 100644 index 0000000..502400e --- /dev/null +++ b/modules/attrs/youtube/default.nix @@ -0,0 +1,16 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.youtube = moduleWithSystem ({...}: let + modules = with self.nixosModules; [ + obs-studio + wshowkeys + woomer + mumble + ]; + in { + imports = modules; + }); +} diff --git a/modules/chataigne/Chataigne-linux-x64-1.10.3.AppImage b/modules/chataigne/Chataigne-linux-x64-1.10.3.AppImage deleted file mode 100755 index 04c4965..0000000 Binary files a/modules/chataigne/Chataigne-linux-x64-1.10.3.AppImage and /dev/null differ diff --git a/modules/chataigne/flake.lock b/modules/chataigne/flake.lock deleted file mode 100644 index 0f6d111..0000000 --- a/modules/chataigne/flake.lock +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodes": { - "nixpkgs": { - "locked": { - "lastModified": 1780952837, - "narHash": "sha256-Fwd1+spDtQ0hDyBwme6ufG3n4mY0UrjjFdYHv+G/Hds=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "e820eb4a444b46a19b2e03e8dfd2359439ff30fe", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-25.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/modules/chataigne/flake.nix b/modules/chataigne/flake.nix deleted file mode 100644 index d8c5d2e..0000000 --- a/modules/chataigne/flake.nix +++ /dev/null @@ -1,82 +0,0 @@ -{ - description = "Local wrapper for Chataigne AppImage"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; - }; - - outputs = { - self, - nixpkgs, - }: let - system = "x86_64-linux"; - pkgs = import nixpkgs {inherit system;}; - - # The libraries you requested - deps = with pkgs; [ - curlFull - gnutls - libxrandr - alsa-lib - freetype - avahi - libglvnd - curl - SDL2 - hidapi - libpulseaudio - lz4 - openssl - libcap - libxcrypt - libgcrypt - libbsd - zlib - glib - ]; - - # Wrap the local AppImage file - chataigne-bin = pkgs.appimageTools.wrapType2 { - pname = "chataigne"; - version = "1.10.3"; - # This points to the file in the same directory as flake.nix - src = ./Chataigne-linux-x64-1.10.3.AppImage; - extraPkgs = pkgs: deps; - }; - - # Create the Desktop Entry - chataigne-desktop = pkgs.makeDesktopItem { - name = "chataigne"; - exec = "chataigne"; - icon = "chataigne"; - comment = "Modular machine for art and technology"; - desktopName = "Chataigne"; - categories = [ - "AudioVideo" - "Development" - ]; - }; - in { - # packages.${system}.default = chataigne-bin; - - devShells.${system}.default = pkgs.mkShell { - # Packages you want available in your shell - buildInputs = [ - chataigne-bin - ]; - - # Environmental variables or shell hooks - shellHook = '' - echo "something" - ''; - }; - # This allows you to run 'nix run' or install it via system config - packages.${system}.default = pkgs.symlinkJoin { - name = "chataigne"; - paths = [ - chataigne-bin - chataigne-desktop - ]; - }; - }; -} diff --git a/modules/empty.nix b/modules/empty.nix new file mode 100644 index 0000000..0e20366 --- /dev/null +++ b/modules/empty.nix @@ -0,0 +1,28 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.name = moduleWithSystem ({ + pkgs, + self', + inputs', + ... + }: let + modules = with self.nixosModules; []; + in { + imports = modules; + programs.name = { + enable = true; + package = self'.packages.hello; + }; + }); + perSystem = { + pkgs, + lib, + self', + ... + }: { + packages.hello = pkgs.hello; + }; +} diff --git a/modules/features/davinci/default.nix b/modules/features/davinci/default.nix new file mode 100644 index 0000000..706a27f --- /dev/null +++ b/modules/features/davinci/default.nix @@ -0,0 +1,14 @@ +{ + moduleWithSystem, + self, + ... +}: { + flake.nixosModules.davinci = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + davinci-resolve + ]; + }); + perSystem = {inputs', ...}: { + packages.davinci-resolve = inputs'.davinci.packages.default; + }; +} diff --git a/modules/features/git/default.nix b/modules/features/git/default.nix new file mode 100644 index 0000000..a6b83dc --- /dev/null +++ b/modules/features/git/default.nix @@ -0,0 +1,40 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.git = { + pkgs, + lib, + ... + }: { + programs.git = { + enable = true; + package = self.packages.${pkgs.stdenv.hostPlatform.system}.git; + }; + programs.gnupg.agent = { + enable = true; + pinentryPackage = pkgs.pinentry-all; + }; + }; + perSystem = { + pkgs, + lib, + self', + ... + }: { + packages.git = inputs.wrappers.wrappers.git.wrap { + inherit pkgs; + runtimePkgs = with pkgs; [ + git-secret + ]; + settings = { + user = { + email = "admin@voidarc.co.uk"; + name = "voidarc"; + }; + credential.helper = "store"; + }; + }; + }; +} diff --git a/modules/features/gotify-desktop/default.nix b/modules/features/gotify-desktop/default.nix new file mode 100644 index 0000000..22beefb --- /dev/null +++ b/modules/features/gotify-desktop/default.nix @@ -0,0 +1,36 @@ +{ +inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.gotify-desktop = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + gotify-desktop + ]; + }); + perSystem = { + pkgs, + inputs', + ... + }: { + packages = { + gotify-desktop = let + # Requires gpg keyring cert in order to get api key + config-file = pkgs.writeText "config.toml" '' + [gotify] + url = "wss://ntfy.voidarc.co.uk:443" + token = { command = "${pkgs.gnupg}/bin/gpg --quiet --batch --decrypt ${./gotify-key.secret}" } + [notification] + min_priority = 1 + ''; + in + inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = inputs'.gotify-desktop.packages.default; + flags = { + "-c" = config-file; + }; + }); + }; + }; +} diff --git a/modules/features/gotify-desktop/gotify-key.secret b/modules/features/gotify-desktop/gotify-key.secret new file mode 100644 index 0000000..dcae609 Binary files /dev/null and b/modules/features/gotify-desktop/gotify-key.secret differ diff --git a/modules/features/hyprland/default.nix b/modules/features/hyprland/default.nix new file mode 100644 index 0000000..981f328 --- /dev/null +++ b/modules/features/hyprland/default.nix @@ -0,0 +1,80 @@ +{ + moduleWithSystem, + self, + inputs, + ... +}: { + flake.nixosModules.hyprland = moduleWithSystem ({ + self', + pkgs, + inputs', + ... + }: {config, ...}: let + modules = with self.nixosModules; [ + audio + systemTheme + ]; + + runtimePkgs = self'.packages.hyprland.passthru.runtimePackages; + lib = pkgs.lib; + + runtimeTarget = name: pkg: + if config.security.wrappers ? ${name} + then "/run/wrappers/bin/${name}" + else lib.getExe pkg; + in { + imports = modules; + programs.hyprland = { + enable = true; + package = self'.packages.hyprland; + }; + + services.displayManager.defaultSession = "hyprland"; + services.xserver.enable = true; + security.polkit.enable = true; + + environment.systemPackages = with pkgs; [ + hyprlock + gsettings-desktop-schemas + ]; + + system.activationScripts.hyprRuntimeEnv = lib.stringAfter ["specialfs"] '' + mkdir -p /run/hypr-runtime-env/bin + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: pkg: '' + ln -sfn ${runtimeTarget name pkg} /run/hypr-runtime-env/bin/${name} + '') + runtimePkgs)} + ''; + + system.activationScripts.hyprConfig = lib.stringAfter ["specialfs"] '' + mkdir -p /run/hypr/config + ln -sfn ${inputs'.hyprland.packages.repo-files}/* /run/hypr/config + ''; + }); + perSystem = { + self', + system, + inputs', + ... + }: { + packages = { + hyprland = inputs'.hyprland.packages.default.override { + flags."--config" = "/run/hypr/config/hyprland.lua"; + env."MODULES_ROOT" = "/run/hypr/config/modules"; + runtimePackages = + inputs.hyprland.lib.defaultRuntimePkgs.${system} + // { + wpaperd = self'.packages.wpaperd; + kitty = self'.packages.kitty; + gotify-desktop = self'.packages.gotify-desktop; + otter-launcher = self'.packages.otter-launcher; + quickshell = self'.packages.quickshell; + wshowkeys = self'.packages.wshowkeys; + waybar = self'.packages.waybar; + wlogout = self'.packages.wlogout; + way-edges = self'.packages.way-edges; + }; + }; + }; + }; +} diff --git a/modules/features/i3/config b/modules/features/i3/config new file mode 100644 index 0000000..17aff20 --- /dev/null +++ b/modules/features/i3/config @@ -0,0 +1,71 @@ +set $mod Mod4 +set $term kitty +set $menu dmenu_run + +exec --no-startup-id xrandr --output HDMI-1 --mode 1920x1080 --rate 60 --pos -1920x0 --output DP-1 --mode 1920x1080 --rate 60 --pos 0x0 --output DP-2 --mode 1920x1080 --rate 60 --pos 1920x0 + +font pango:FiraMono Nerd Font 10 + +workspace 1 output DP-1 +workspace 2 output HDMI-A-1 +workspace 3 output DP-2 + +# Window functions +bindsym $mod+BackSpace kill +bindsym $mod+b fullscreen toggle + +# Apps +bindsym $mod+Return exec --no-startup-id $term +bindsym $mod+d exec --no-startup-id $menu +bindsym $mod+f exec --no-startup-id firefox +bindsym $mod+s exec --no-startup-id nemo + +# Focus windows +bindsym $mod+k focus up +bindsym $mod+j focus down +bindsym $mod+h focus left +bindsym $mod+l focus right + +# Move windows +bindsym $mod+Shift+h move left +bindsym $mod+Shift+l move right +bindsym $mod+Shift+k move up +bindsym $mod+Shift+j move down + +# Workspaces +bindsym $mod+q workspace number 1 +bindsym $mod+w workspace number 2 +bindsym $mod+e workspace number 3 +bindsym $mod+r workspace number 4 +bindsym $mod+t workspace number 5 +bindsym $mod+y workspace number 6 +bindsym $mod+u workspace number 7 +bindsym $mod+i workspace number 8 +bindsym $mod+o workspace number 9 +bindsym $mod+p workspace number 10 + +# Move container to workspace +bindsym $mod+Shift+q move container to workspace number 1 +bindsym $mod+Shift+w move container to workspace number 2 +bindsym $mod+Shift+e move container to workspace number 3 +bindsym $mod+Shift+r move container to workspace number 4 +bindsym $mod+Shift+t move container to workspace number 5 +bindsym $mod+Shift+y move container to workspace number 6 +bindsym $mod+Shift+u move container to workspace number 7 +bindsym $mod+Shift+i move container to workspace number 8 +bindsym $mod+Shift+o move container to workspace number 9 +bindsym $mod+Shift+p move container to workspace number 10 + +# Logout menu +bindsym $mod+Shift+a exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'" + +# Reload +bindsym $mod+Shift+m reload + +# Drag windows with titlebar +tiling_drag modifier titlebar + +# Bar +bar { + status_command i3status +} diff --git a/modules/features/i3/default.nix b/modules/features/i3/default.nix new file mode 100644 index 0000000..5551d1a --- /dev/null +++ b/modules/features/i3/default.nix @@ -0,0 +1,48 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.i3 = moduleWithSystem ({ + pkgs, + self', + ... + }: { + services.xserver = { + enable = true; + + desktopManager = { + xterm.enable = false; + }; + + windowManager.i3 = { + enable = true; + package = self'.packages.i3; + extraPackages = with pkgs; + [ + dmenu + i3status + xinit + ]; + }; + }; + }); + perSystem = {pkgs, self', ...}: { + packages.i3 = inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = pkgs.i3; + runtimePkgs = with pkgs; + [ + xrandr + firefox + ] + ++ (with self'.packages; [ + kitty + nemo + ]); + flags = { + "-c" = ./config; + }; + }); + }; +} diff --git a/modules/features/kitty/default.nix b/modules/features/kitty/default.nix new file mode 100644 index 0000000..91b4252 --- /dev/null +++ b/modules/features/kitty/default.nix @@ -0,0 +1,49 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.kitty = moduleWithSystem ( + {self'}: { + environment.systemPackages = with self'.packages; [ + kitty + ]; + } + ); + perSystem = {pkgs, ...}: { + packages.kitty = let + fira-mono = pkgs.nerd-fonts.fira-mono; + fontsConf = pkgs.makeFontsConf { + fontDirectories = [fira-mono]; + }; + in + inputs.wrappers.wrappers.kitty.wrap { + inherit pkgs; + environment = { + "FONTCONFIG_FILE" = "${fontsConf}"; + }; + font = { + name = "FiraMono Nerd Font Mono"; + size = 11; + }; + settings = { + font_size = 11; + scrollbar = "never"; + pixel_scroll = false; + window_padding_width = 9; + background_opacity = 0.50; + confirm_os_window_close = 0; + enable_audio_bell = false; + cursor_trail = 1; + cursor_trail_start_threshold = 1; + cursor_trail_color = "#cba6f7"; + cursor_shape = "beam"; + allow_remote_control = true; + }; + keybindings = { + "ctrl+backspace" = "send_text all \\x17"; + }; + themeFile = "Catppuccin-Mocha"; + }; + }; +} diff --git a/modules/features/lazygit/default.nix b/modules/features/lazygit/default.nix new file mode 100644 index 0000000..f2f3e9e --- /dev/null +++ b/modules/features/lazygit/default.nix @@ -0,0 +1,51 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.lazygit = { + pkgs, + lib, + ... + }: { + environment.systemPackages = with pkgs; [ + self.packages.${pkgs.stdenv.hostPlatform.system}.lazygit + ]; + }; + perSystem = { + pkgs, + lib, + self', + ... + }: let + config-file = pkgs.writeText "config.yml" '' + gui: + nerdFontsVersion: "3" + + customCommands: + - key: 'p' + context: 'global' + command: 'git pull --recurse-submodules' + loadingText: 'Pulling with submodules' + output: 'log' + - key: '' + context: 'global' + command: 'git pull' + loadingText: 'Pulling remote repo' + output: 'log' + ''; + in { + packages.lazygit = inputs.wrappers.lib.wrapPackage ({ + config, + wlib, + lib, + ... + }: { + inherit pkgs; + package = pkgs.lazygit; + flags = { + "--use-config-file" = config-file; + }; + }); + }; +} diff --git a/modules/features/mumble/default.nix b/modules/features/mumble/default.nix new file mode 100644 index 0000000..bdb8d1f --- /dev/null +++ b/modules/features/mumble/default.nix @@ -0,0 +1,75 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.mumble = { + pkgs, + lib, + ... + }: let + modules = with self.nixosModules; [ + audio + ]; + in { + imports = modules; + services.murmur = { + enable = true; + bandwidth = 540000; + bonjour = true; + password = "password"; + autobanTime = 0; + }; + + environment.systemPackages = with pkgs; [ + mumble + ]; + + services.pipewire.extraConfig.pipewire = { + "97-null-sink" = { + "context.objects" = [ + { + factory = "adapter"; + args = { + "factory.name" = "support.null-audio-sink"; + "node.name" = "Null-Sink"; + "node.description" = "Null Sink"; + "media.class" = "Audio/Sink"; + "audio.position" = "FL,FR"; + }; + } + { + factory = "adapter"; + args = { + "factory.name" = "support.null-audio-sink"; + "node.name" = "Null-Source"; + "node.description" = "Null Source"; + "media.class" = "Audio/Source"; + "audio.position" = "FL,FR"; + }; + } + ]; + }; + "98-virtual-mic" = { + "context.modules" = [ + { + name = "libpipewire-module-loopback"; + args = { + "audio.position" = "FL,FR"; + "node.description" = "Mumble as Microphone"; + "capture.props" = { + # Mumble's output node name. + "node.target" = "Mumble"; + "node.passive" = true; + }; + "playback.props" = { + "node.name" = "Virtual-Mumble-Microphone"; + "media.class" = "Audio/Source"; + }; + }; + } + ]; + }; + }; + }; +} diff --git a/modules/features/nvim/default.nix b/modules/features/nvim/default.nix new file mode 100644 index 0000000..f6e706e --- /dev/null +++ b/modules/features/nvim/default.nix @@ -0,0 +1,11 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.nvim = moduleWithSystem ({self', ...}: { + programs.neovim = { + enable = true; + package = self'.packages.nvim; + }; + }); + perSystem = {inputs', ...}: { + packages.nvim = inputs'.nvim.packages.default; + }; +} diff --git a/modules/features/obs-studio/default.nix b/modules/features/obs-studio/default.nix new file mode 100644 index 0000000..0b61ed9 --- /dev/null +++ b/modules/features/obs-studio/default.nix @@ -0,0 +1,8 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.obs-studio = moduleWithSystem ({...}: { + programs.obs-studio = { + enable = true; + enableVirtualCamera = true; + }; + }); +} diff --git a/modules/features/omnisearch/default.nix b/modules/features/omnisearch/default.nix new file mode 100644 index 0000000..b3a37aa --- /dev/null +++ b/modules/features/omnisearch/default.nix @@ -0,0 +1,14 @@ +{ + moduleWithSystem, + inputs, + ... +}: { + flake.nixosModules.omnisearch = moduleWithSystem ({...}: let + modules = [ + inputs.omnisearch.nixosModules.default + ]; + in { + imports = modules; + services.omnisearch.enable = true; + }); +} diff --git a/modules/features/otter-launcher/cat.png b/modules/features/otter-launcher/cat.png new file mode 100644 index 0000000..5eccee7 Binary files /dev/null and b/modules/features/otter-launcher/cat.png differ diff --git a/modules/features/otter-launcher/config.toml b/modules/features/otter-launcher/config.toml new file mode 100644 index 0000000..a65fd9a --- /dev/null +++ b/modules/features/otter-launcher/config.toml @@ -0,0 +1,111 @@ +[general] +default_module = "app" # module to run when no prefix is matched +empty_module = "app" # run with an empty prompt +exec_cmd = "zsh -c" # exec command of your shell +vi_mode = false # set true to use vi keybinds, false emacs keybinds +esc_to_abort = true # useful for vi users +cheatsheet_entry = "?" # when prompted, will show a list of configured modules +cheatsheet_viewer = "less -R; clear" # command to show cheatsheet; through piping stdout +clear_screen_after_execution = false +loop_mode = false # don't quit after executing a module, useful with scratchpads; stderr is hidden in loop mode +external_editor = "nvim" # if set, press ctrl+x ctrl+ee (or v in vi normal mode) to edit prompt in the specified program +delay_startup = 0 # sometimes the otter runs too fast even before the terminal window is ready; this slows it down by milliseconds; useful when chafa image is skewed + +[interface] +# use three quotes to write longer codes +header = """ + \x1b[1;38;2;203;166;247m$USER@nixos\x1b[0m + """ +header_cmd = '' # run a command and print stdout above the header +header_cmd_trimmed_lines = 0 # remove trailing lines from header_cmd output, in case of some programs appending excessive empty lines +place_holder = "execute" # at the input field +suggestion_mode = "list" # available options: list, hint +separator = """ +$( \ + text=" "; \ + printf "\u001B[0;90m$text \ + $(printf -v line '%*s' \"$(( COLUMNS - $(printf "$text" | wc -m) - 3 ))\" ''; printf '%s' \"${line// /─}\")" \ +)""" +footer = "" # add a line after suggestion list +suggestion_lines = 7 # 0 to disable suggestions and tab completion +list_prefix = " " +selection_prefix = "\u001B[31;1m " +prefix_padding = 3 # format prefixes to have a uniformed width +default_module_message = " \u001B[33mlaunch\u001B[0m app" # shown when the default module is in use +empty_module_message = "" # shown when the empty module is in use +customized_list_order = false # false to list modules alphabetically; true to list as per the configured order in the below [[modules]] section +indicator_with_arg_module = " * " # the sign showing whether a module should run with an argument +indicator_no_arg_module = " " +# below color options affect all modules; per-module coloring can be configured using ansi codes individually +prefix_color = "\u001B[33m" +description_color = "\u001B[39m" +place_holder_color = "\u001B[30m" +hint_color = "\u001B[30m" # suggestion color in hint mode +# move the interface rightward or downward +move_interface_right = 21 +move_interface_down = 0 + +[[modules]] +description = "programs" +prefix = "app" +cmd = """ +hyprctl dispatch 'hl.dsp.window.resize({x = 700, y = 700, window = activewindow})' && +hyprctl dispatch 'hl.dsp.window.center({window = activewindow})'&& +hyprctl dispatch "hl.dsp.exec_cmd('$(fsel --no-exec)')" +""" + +[[modules]] +description = "bluetooth" +prefix = "bl" +cmd = """ +hyprctl dispatch 'hl.dsp.window.resize({x = 650, y = 400, window = activewindow})' && +hyprctl dispatch 'hl.dsp.window.center({window = activewindow})'&& +bluetui +""" + +[[modules]] +description = "nixos wiki" +prefix = "nw" +cmd = """ +hyprctl dispatch "hl.dsp.exec_cmd('firefox --new-window https://wiki.nixos.org/w/index.php?search={}')" +""" +with_argument = true +url_encode = true +unbind_proc = true + +[[modules]] +description = "nixpkgs" +prefix = "nix" +cmd = """ +hyprctl dispatch "hl.dsp.exec_cmd('firefox --new-window https://search.nixos.org/packages?query={}')" +""" +with_argument = true +url_encode = true +unbind_proc = true + +[[modules]] +description = "jellyfin" +prefix = "jf" +cmd = """ +hyprctl dispatch 'hl.dsp.exec_cmd("kitty --class jf-tui -e jellyfin-tui", {workspace = "special:music"})' +""" + +[[modules]] +description = "youtube" +prefix = "y" +cmd = """ +hyprctl dispatch "hl.dsp.exec_cmd('firefox --new-window https://www.youtube.com')" +""" +with_argument = false +url_encode = true +unbind_proc = true + +[[modules]] +description = "whatsapp" +prefix = "w" +cmd = """ +hyprctl dispatch "hl.dsp.exec_cmd('firefox --new-window https://web.whatsapp.com')" +""" +with_argument = false +url_encode = true +unbind_proc = true diff --git a/modules/features/otter-launcher/default.nix b/modules/features/otter-launcher/default.nix new file mode 100644 index 0000000..13667b9 --- /dev/null +++ b/modules/features/otter-launcher/default.nix @@ -0,0 +1,44 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.otter-launcher = moduleWithSystem ({self', ...}: { + environment.systemPackages = [ + self'.packages.otter-launcher + ]; + }); + perSystem = { + pkgs, + lib, + self', + inputs', + ... + }: { + packages = { + otter-launcher = let + extra-config = '' + [overlay] + overlay_cmd = "${lib.getExe pkgs.kitty} +kitten icat --fit height --align left --no-trailing-newline ${./cat.png}" + overlay_trimmed_lines = 0 + ''; + final-config = pkgs.writeText "config.toml" '' + ${extra-config} + + ${builtins.readFile ./config.toml} + ''; + in + inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = inputs'.otter-launcher.packages.default; + runtimePkgs = with pkgs; [ + fsel + bluetui + ]; + flags = { + "-c" = final-config; + }; + }); + }; + }; +} diff --git a/modules/features/quickshell/default.nix b/modules/features/quickshell/default.nix new file mode 100644 index 0000000..dba12eb --- /dev/null +++ b/modules/features/quickshell/default.nix @@ -0,0 +1,22 @@ +{ + moduleWithSystem, + inputs, + ... +}: { + flake.nixosModules.quickshell = moduleWithSystem ({ + self', + pkgs, + ... + }: { + environment.systemPackages = with self'.packages; [ + quickshell + ]; + }); + perSystem = {pkgs, ...}: { + packages.quickshell = inputs.wrappers.wrappers.quickshell.wrap { + inherit pkgs; + configDir = inputs.quickshell; + configFile = "${inputs.quickshell}/shell.qml"; + }; + }; +} diff --git a/modules/features/sddm/autologin.nix b/modules/features/sddm/autologin.nix new file mode 100644 index 0000000..c43e4c8 --- /dev/null +++ b/modules/features/sddm/autologin.nix @@ -0,0 +1,16 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.sddm-autologin = { + pkgs, + lib, + ... + }: { + services.displayManager = { + autoLogin.enable = true; + autoLogin.user = "user01"; + }; + }; +} diff --git a/modules/features/sddm/default.nix b/modules/features/sddm/default.nix new file mode 100644 index 0000000..b0c2c56 --- /dev/null +++ b/modules/features/sddm/default.nix @@ -0,0 +1,25 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.sddm = { + pkgs, + lib, + ... + }: { + environment.systemPackages = [ + (pkgs.catppuccin-sddm.override { + flavor = "mocha"; + font = "Fira Mono Nerd Font"; + fontSize = "11"; + background = null; + }) + ]; + services.displayManager.sddm = { + enable = true; + theme = "catppuccin-mocha-mauve"; + package = pkgs.kdePackages.sddm; + }; + }; +} diff --git a/modules/features/steam/default.nix b/modules/features/steam/default.nix new file mode 100644 index 0000000..943467c --- /dev/null +++ b/modules/features/steam/default.nix @@ -0,0 +1,30 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.steam = moduleWithSystem ({ + pkgs, + unfreePkgs, + inputs', + lib, + ... + }: { + # If buying isn't owning than piracy isn't stealing + environment.systemPackages = [ + inputs'.sls-steam.packages.default + ]; + programs.steam = { + enable = true; + protontricks.enable = true; + extraCompatPackages = with pkgs; [ + proton-ge-bin + ]; + package = unfreePkgs.steam.override { + extraEnv = { + LD_AUDIT = "${ + inputs'.sls-steam.packages.sls-steam + }/library-inject.so:${ + inputs'.sls-steam.packages.sls-steam + }/SLSsteam.so"; + }; + }; + }; + }); +} diff --git a/modules/features/tailscale/default.nix b/modules/features/tailscale/default.nix new file mode 100644 index 0000000..f15334e --- /dev/null +++ b/modules/features/tailscale/default.nix @@ -0,0 +1,11 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.tailscale = moduleWithSystem ({...}: { + services.tailscale = { + enable = true; + }; + }); +} diff --git a/modules/features/way-edges/config.jsonc b/modules/features/way-edges/config.jsonc new file mode 100644 index 0000000..4bc0189 --- /dev/null +++ b/modules/features/way-edges/config.jsonc @@ -0,0 +1,60 @@ +{ + "allow-trailing-commas": true, + "widgets": [ + { + "type": "slider", + "edge": "right", + "position": "top", + "thickness": 30, + "length": "25%", + "margins": { + "top": "50%" + }, + "border-width": 4, + "border-color": "#cba6f7ff", + "fg-color": "#cba6f7bb", + "bg-color": "#31324466", + "fg-text-color": "#11111bff", + "bg-text-color": "#bac2dedd", + "transition-duration": 100, + "redraw-only-on-internal-update": true, + "radius": 10, // corner radius + "obtuse-angle": 90, // in degrees(90~180). controls how much curve the widget has + "scroll-unit": 0.005, + "pinnable": false, + "preset": { + "type": "speaker", + "animation-curve": "Linear", // mute animation + "mute-text-color": "#f38ba8ff", + "mute-color": "#f38ba8bb", + }, + }, + { + "type": "slider", + "edge": "right", + "position": "top", + "thickness": 30, + "length": "25%", + "margins": { + "top": "25%" + }, + "border-width": 4, + "border-color": "#f9e2afff", + "fg-color": "#f9e2afbb", + "bg-color": "#31324466", + "fg-text-color": "#11111bff", + "bg-text-color": "#bac2dedd", + "transition-duration": 100, + "redraw-only-on-internal-update": true, + "radius": 10, // corner radius + "obtuse-angle": 90, // in degrees(90~180). controls how much curve the widget has + "scroll-unit": 0.005, + "pinnable": false, + "preset": { + "type": "backlight", + "device": "intel_backlight", // this is the name of the device. Find it under `/sys/class/backlight/` It should be something like `nvidia_0`, `intel_0`, etc. + }, + }, + ] +} + diff --git a/modules/features/way-edges/default.nix b/modules/features/way-edges/default.nix new file mode 100644 index 0000000..0ae116e --- /dev/null +++ b/modules/features/way-edges/default.nix @@ -0,0 +1,20 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.way-edges = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + way-edges + ]; + }); + perSystem = {pkgs, ...}: { + packages.way-edges = inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = pkgs.way-edges; + flags = { + "--config-path" = ./config.jsonc; + }; + }); + }; +} diff --git a/modules/features/waybar/default.nix b/modules/features/waybar/default.nix new file mode 100644 index 0000000..e07b4ae --- /dev/null +++ b/modules/features/waybar/default.nix @@ -0,0 +1,42 @@ +{ + moduleWithSystem, + inputs, + ... +}: { + flake.nixosModules.waybar = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + waybar + ]; + }); + perSystem = {pkgs, ...}: { + packages.waybar = inputs.wrappers.wrappers.waybar.wrap { + inherit pkgs; + "style.css".path = ./style.css; + configFile.content = '' + { + "include": [ + "${./modules.jsonc}" + ], + "height": 20, + "margin": "3 6", + "reload_style_on_change": true, + "position": "top", + "modules-left": [ + "custom/logo", + "hyprland/workspaces" + ], + "modules-center": [ + "mpris" + ], + "modules-right": [ + "network", + "bluetooth", + "custom/notifs", + "battery", + "clock" + ] + } + ''; + }; + }; +} diff --git a/modules/features/waybar/modules.jsonc b/modules/features/waybar/modules.jsonc new file mode 100644 index 0000000..bf72c10 --- /dev/null +++ b/modules/features/waybar/modules.jsonc @@ -0,0 +1,78 @@ +{ + "custom/logo": { + "format": "" + }, + "mpris": { + "format": "{status_icon} {title} - {artist}", + "title-len": 50, + "artist-len": 20, + "status-icons": { + "playing": "", + "paused": "" + } + }, + "network": { + "format": "󰤭", + "format-ethernet": "󰈀", + "format-wifi": "{icon}", + "format-icons": [ + "󰤟", + "󰤢", + "󰤥", + "󰤨" + ], + "format-alt": "{ipaddr} / {gwaddr}", + "tooltip-format": "{ifname} - {essid}" + }, + "bluetooth": { + "format": "󰂲", + "format-connected": "󰂱", + "tooltip-format": "{status} - {device_alias}", + "on-click": "kitty --class otter --title otter-launcher -e sh -c 'sleep 0.05 && otter-launcher bl'" + }, + "battery": { + "format": "{icon} {capacity}%", + "format-plugged": "󰂄 {capacity}%", + "format-charging": "󰂄 {capacity}%", + "states": { + "warning": 30, + "critical": 15 + }, + "format-icons": [ + "", + "", + "", + "" + ] + }, + "custom/notifs": { + "format": "", + "on-click": "kitty --class otter --title otter-launcher -e sh -c 'sleep 0.05 && otter-launcher dunst'" + }, + "memory": { + "format": " {percentage}%", + "tooltip-format": "{used:0.1f}GiB, {swapUsed:0.1f}GiB Swap" + }, + "cpu": { + "format": " {usage}%" + }, + "clock": { + "interval": 1, + "format": "{:%T}", + "tooltip-format": "{calendar}", + "calendar": { + "mode" : "year", + "mode-mon-col" : 3, + "weeks-pos" : "right", + "on-scroll" : 1, + "format": { + "months": "{}", + "days": "{}", + "weeks": "W{}", + "weekdays": "{}", + "today": "{}" + } + }, + } +} + diff --git a/modules/features/waybar/style.css b/modules/features/waybar/style.css new file mode 100644 index 0000000..accc10e --- /dev/null +++ b/modules/features/waybar/style.css @@ -0,0 +1,158 @@ +* { + font-family: "Fira Mono Nerd Font Propo"; + font-size: 16px; + font-weight: bold; + min-height: 16px; + margin: 0; + padding: 0; +} + +window#waybar { + background: transparent; +} + +.module { + background-color: rgba(30, 30, 46, 0.8); + margin: 0 3px; + padding: 0 9px; + border-radius: 7px; +} + +#custom-logo { + background-color: #cba6f7; + color: #1e1e2e; + font-size: 21px; +} + +#workspaces { + padding: 3px 4px; +} + +#workspaces button { + background-color: #585b70; + margin: 0 2px; + padding: 0 2px; + border-radius: 2px; +} + +#workspaces button:first-child { + border-radius: 5px 2px 2px 5px; + margin: 0; + margin-right: 2px; +} + +#workspaces button:last-child { + border-radius: 2px 5px 5px 4px; + margin: 0; + margin-left: 2px; +} + +#workspaces button:only-child { + border-radius: 5px; + padding: 0 12px; + margin: 0 1px; +} + +#workspaces button.active { + background-color: #b4befe; + color: #313244; +} + +#mpris { + font-size: 14px; + transition: + color 0.5s, + background-color 0.5s; +} + +#mpris.paused { + color: #f2cdcd; +} + +#mpris.playing { + color: rgba(30, 30, 46, 0.8); + background-color: #ca9ee6; +} + +#network { + background-color: #f38ba8; + color: #1e1e2e; +} + +#bluetooth { + background-color: #fab387; + color: #1e1e2e; +} + +#custom-notifs { + background-color: #f9e2af; + color: #1e1e2e; +} + +#battery { + background-color: #a6e3a1; + color: #1e1e2e; + transition: + color 0.5s, + background-color 0.5s, + linear-gradient 0.4s; +} + +#battery.warning { + color: #1e1e2e; + background: #f38ba8; + background: linear-gradient( + 135deg, + rgba(243, 139, 168, 1) 0%, + rgba(166, 218, 149, 1) 65%, + rgba(166, 218, 149, 1) 100% + ); +} + +#battery.charging { + background-color: #40a02b; + background: #cba6f7; + background: linear-gradient( + 135deg, + rgba(203, 166, 247, 1) 0%, + rgba(166, 218, 149, 1) 65%, + rgba(166, 218, 149, 1) 100% + ); +} + +#battery.plugged { + background-color: #40a02b; + background: #cba6f7; + background: linear-gradient( + 135deg, + rgba(203, 166, 247, 1) 0%, + rgba(166, 218, 149, 1) 65%, + rgba(166, 218, 149, 1) 100% + ); +} + +#battery.critical { + color: #f38ba8; +} + +#memory { + padding-right: 3px; + border-radius: 7px 0 0 7px; + margin-right: 0; + background-color: #89dceb; + color: #1e1e2e; +} + +#cpu { + padding-left: 3px; + border-radius: 0 7px 7px 0; + margin-left: 0; + background-color: #89dceb; + color: #1e1e2e; +} + +#clock { + background-color: #89b4fa; + color: #1e1e2e; +} + diff --git a/modules/features/weylus/default.nix b/modules/features/weylus/default.nix new file mode 100644 index 0000000..ccb6552 --- /dev/null +++ b/modules/features/weylus/default.nix @@ -0,0 +1,9 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.weylus = moduleWithSystem ({inputs', ...}: { + programs.weylus = { + enable = true; + package = inputs'.weylus.packages.default; + users = ["user01"]; + }; + }); +} diff --git a/modules/features/wlogout/default.nix b/modules/features/wlogout/default.nix new file mode 100644 index 0000000..1165781 --- /dev/null +++ b/modules/features/wlogout/default.nix @@ -0,0 +1,22 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.wlogout = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + wlogout + ]; + }); + perSystem = {pkgs, ...}: { + packages.wlogout = inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = pkgs.wlogout; + flags = { + "--css" = ./style.css; + "--layout" = ./layout; + "--buttons-per-row" = "5"; + }; + }); + }; +} diff --git a/modules/features/wlogout/icons/exit.png b/modules/features/wlogout/icons/exit.png new file mode 100644 index 0000000..6f061f2 Binary files /dev/null and b/modules/features/wlogout/icons/exit.png differ diff --git a/modules/features/wlogout/icons/lock.png b/modules/features/wlogout/icons/lock.png new file mode 100644 index 0000000..51ca4af Binary files /dev/null and b/modules/features/wlogout/icons/lock.png differ diff --git a/modules/features/wlogout/icons/power.png b/modules/features/wlogout/icons/power.png new file mode 100644 index 0000000..9003c18 Binary files /dev/null and b/modules/features/wlogout/icons/power.png differ diff --git a/modules/features/wlogout/icons/reload.png b/modules/features/wlogout/icons/reload.png new file mode 100644 index 0000000..05e0200 Binary files /dev/null and b/modules/features/wlogout/icons/reload.png differ diff --git a/modules/features/wlogout/icons/slwwp.png b/modules/features/wlogout/icons/slwwp.png new file mode 100644 index 0000000..24e190f Binary files /dev/null and b/modules/features/wlogout/icons/slwwp.png differ diff --git a/modules/features/wlogout/layout b/modules/features/wlogout/layout new file mode 100755 index 0000000..440783f --- /dev/null +++ b/modules/features/wlogout/layout @@ -0,0 +1,30 @@ +{ + "label" : "lock", + "action" : "hyprlock", + "text" : "Lock", + "keybind" : "l" +} +{ + "label" : "logout", + "action" : "hyprctl dispatch 'hl.dsp.exit()'" , + "text" : "Logout", + "keybind" : "e" +} +{ + "label" : "shutdown", + "action" : "systemctl poweroff", + "text" : "Shutdown", + "keybind" : "s" +} +{ + "label" : "suspend", + "action" : "systemctl suspend", + "text" : "Sleep", + "keybind" : "u" +} +{ + "label" : "reboot", + "action" : "systemctl reboot", + "text" : "Reboot", + "keybind" : "r" +} diff --git a/modules/features/wlogout/style.css b/modules/features/wlogout/style.css new file mode 100755 index 0000000..e82c0e3 --- /dev/null +++ b/modules/features/wlogout/style.css @@ -0,0 +1,73 @@ +* { + background-image: none; + box-shadow: none; +} + +window { + background-color: rgba(12, 12, 12, 0.05); +} + +button { + border-radius: 0; + border-color: #cba6f7; + text-decoration-color: #ffffff; + color: #FFFFFF; + background-color: #313244; + border-style: solid none; + border-width: 4px; + background-repeat: no-repeat; + background-position: 50% 30%; + background-size: 75%; +} + +button:first-child { + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; +} + +button:last-child { + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} + +#lock { + border-left-style: solid; + background-image: image(url("./icons/lock.png")); +} + +#logout { + background-image: image(url("./icons/exit.png")); +} + +#suspend { + background-image: image(url("./icons/slwwp.png")); +} + +#shutdown { + background-image: image(url("./icons/power.png")); +} + +#reboot { + border-right-style: solid; + background-image: image(url("./icons/reload.png")); +} + +#lock:focus { + background-color: #f38ba8; +} + +#logout:focus { + background-color: #fab387; +} + +#shutdown:focus { + background-color: #a6e3a1; +} + +#suspend:focus { + background-color: #f9e2af; +} + +#reboot:focus { + background-color: #cba6f7; +} diff --git a/modules/features/woomer/default.nix b/modules/features/woomer/default.nix new file mode 100644 index 0000000..ac5f374 --- /dev/null +++ b/modules/features/woomer/default.nix @@ -0,0 +1,26 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.woomer = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + woomer + ]; + }); + perSystem = { + pkgs, + inputs', + ... + }: { + packages.woomer = inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = inputs'.woomer.packages.default; + flags = { + "--monitor" = "DP-1"; + "--output" = "DP-1"; + "--radius" = "2"; + }; + }); + }; +} diff --git a/modules/features/wpaperd/default.nix b/modules/features/wpaperd/default.nix new file mode 100644 index 0000000..03f6fc9 --- /dev/null +++ b/modules/features/wpaperd/default.nix @@ -0,0 +1,35 @@ +{ + moduleWithSystem, + inputs, + ... +}: { + flake.nixosModules.wpaperd = moduleWithSystem ({self', ...}: { + environment.systemPackages = with self'.packages; [ + wpaperd + ]; + }); + perSystem = {pkgs, ...}: { + packages.wpaperd = let + config-file = builtins.toFile "config.toml" '' + [any] + path = "${./wallpapers}" + + [HDMI-A-1] + path = "${./wallpapers/topo1.png}" + + [DP-1] + path = "${./wallpapers/topo2.png}" + + [DP-2] + path = "${./wallpapers/topo3.png}" + ''; + in + inputs.wrappers.lib.wrapPackage ({...}: { + inherit pkgs; + package = pkgs.wpaperd; + flags = { + "--config" = config-file; + }; + }); + }; +} diff --git a/modules/features/wpaperd/wallpapers/aesthetic.jpg b/modules/features/wpaperd/wallpapers/aesthetic.jpg new file mode 100644 index 0000000..2a539c6 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/aesthetic.jpg differ diff --git a/modules/features/wpaperd/wallpapers/bars.jpg b/modules/features/wpaperd/wallpapers/bars.jpg new file mode 100644 index 0000000..9c1668f Binary files /dev/null and b/modules/features/wpaperd/wallpapers/bars.jpg differ diff --git a/modules/features/wpaperd/wallpapers/black-hole.png b/modules/features/wpaperd/wallpapers/black-hole.png new file mode 100644 index 0000000..a1b3e2b Binary files /dev/null and b/modules/features/wpaperd/wallpapers/black-hole.png differ diff --git a/modules/features/wpaperd/wallpapers/city-horizon.jpg b/modules/features/wpaperd/wallpapers/city-horizon.jpg new file mode 100644 index 0000000..0836f1d Binary files /dev/null and b/modules/features/wpaperd/wallpapers/city-horizon.jpg differ diff --git a/modules/features/wpaperd/wallpapers/dragon.jpg b/modules/features/wpaperd/wallpapers/dragon.jpg new file mode 100644 index 0000000..10e226a Binary files /dev/null and b/modules/features/wpaperd/wallpapers/dragon.jpg differ diff --git a/modules/features/wpaperd/wallpapers/flower-field.jpg b/modules/features/wpaperd/wallpapers/flower-field.jpg new file mode 100644 index 0000000..e2b930b Binary files /dev/null and b/modules/features/wpaperd/wallpapers/flower-field.jpg differ diff --git a/modules/features/wpaperd/wallpapers/ocean.png b/modules/features/wpaperd/wallpapers/ocean.png new file mode 100644 index 0000000..8c61b4a Binary files /dev/null and b/modules/features/wpaperd/wallpapers/ocean.png differ diff --git a/modules/features/wpaperd/wallpapers/pink-clouds.jpg b/modules/features/wpaperd/wallpapers/pink-clouds.jpg new file mode 100644 index 0000000..6b45408 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/pink-clouds.jpg differ diff --git a/modules/features/wpaperd/wallpapers/sakura-trees-over-river.jpg b/modules/features/wpaperd/wallpapers/sakura-trees-over-river.jpg new file mode 100644 index 0000000..bfff533 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/sakura-trees-over-river.jpg differ diff --git a/modules/features/wpaperd/wallpapers/sousou-no-frieren-flowers.png b/modules/features/wpaperd/wallpapers/sousou-no-frieren-flowers.png new file mode 100644 index 0000000..f203b75 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/sousou-no-frieren-flowers.png differ diff --git a/modules/features/wpaperd/wallpapers/sunset.jpg b/modules/features/wpaperd/wallpapers/sunset.jpg new file mode 100644 index 0000000..971a1c9 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/sunset.jpg differ diff --git a/modules/features/wpaperd/wallpapers/topo1.png b/modules/features/wpaperd/wallpapers/topo1.png new file mode 100644 index 0000000..7e5c127 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/topo1.png differ diff --git a/modules/features/wpaperd/wallpapers/topo2.png b/modules/features/wpaperd/wallpapers/topo2.png new file mode 100644 index 0000000..aff0c9c Binary files /dev/null and b/modules/features/wpaperd/wallpapers/topo2.png differ diff --git a/modules/features/wpaperd/wallpapers/topo3.png b/modules/features/wpaperd/wallpapers/topo3.png new file mode 100644 index 0000000..39729d0 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/topo3.png differ diff --git a/modules/features/wpaperd/wallpapers/tree.jpg b/modules/features/wpaperd/wallpapers/tree.jpg new file mode 100644 index 0000000..0a84979 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/tree.jpg differ diff --git a/modules/features/wpaperd/wallpapers/unused/wide_lines.png.unused b/modules/features/wpaperd/wallpapers/unused/wide_lines.png.unused new file mode 100644 index 0000000..8774cf4 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/unused/wide_lines.png.unused differ diff --git a/modules/features/wpaperd/wallpapers/unused/wide_lines2.png.unused b/modules/features/wpaperd/wallpapers/unused/wide_lines2.png.unused new file mode 100644 index 0000000..8dcbaa1 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/unused/wide_lines2.png.unused differ diff --git a/modules/features/wpaperd/wallpapers/voyager-8.jpg b/modules/features/wpaperd/wallpapers/voyager-8.jpg new file mode 100644 index 0000000..2f3f205 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/voyager-8.jpg differ diff --git a/modules/features/wpaperd/wallpapers/wallpaper-sun.jpg b/modules/features/wpaperd/wallpapers/wallpaper-sun.jpg new file mode 100755 index 0000000..b1a9ad0 Binary files /dev/null and b/modules/features/wpaperd/wallpapers/wallpaper-sun.jpg differ diff --git a/modules/features/wpaperd/wallpapers/waves.png b/modules/features/wpaperd/wallpapers/waves.png new file mode 100644 index 0000000..8df8e8a Binary files /dev/null and b/modules/features/wpaperd/wallpapers/waves.png differ diff --git a/modules/features/wshowkeys/default.nix b/modules/features/wshowkeys/default.nix new file mode 100644 index 0000000..8b7fbf9 --- /dev/null +++ b/modules/features/wshowkeys/default.nix @@ -0,0 +1,17 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.wshowkeys = moduleWithSystem ({ + self', + pkgs, + ... + }: let + lib = pkgs.lib; + in { + programs.wshowkeys = { + enable = true; + package = self'.packages.wshowkeys; + }; + }); + perSystem = {inputs', ...}: { + packages.wshowkeys = inputs'.wshowkeys.packages.default; + }; +} diff --git a/modules/features/zsh/config.toml b/modules/features/zsh/config.toml new file mode 100644 index 0000000..7c6eabd --- /dev/null +++ b/modules/features/zsh/config.toml @@ -0,0 +1,105 @@ +console_title_template = '{{ .Shell }} in {{ .Folder }}' +version = 3 +final_space = true + +[secondary_prompt] + template = '❯❯ ' + foreground = 'magenta' + background = 'transparent' + +[transient_prompt] + template = '❯ ' + background = 'transparent' + foreground_templates = ['{{if gt .Code 0}}red{{end}}', '{{if eq .Code 0}}magenta{{end}}'] + +[[blocks]] + type = 'prompt' + alignment = 'left' + newline = true + +[[blocks.segments]] +type = 'text' +style = 'plain' +template = ''' +{{- if .Env.DEVSHELL_NAME -}} + {{- $parts := split "|" .Env.DEVSHELL_NAME -}} + {{- range $part := $parts -}} + {{- if $part -}} + {{- $sub := split "/" $part -}} + {{- if eq (len $sub) 2 -}} + <{{ index $sub "_1" }}>{{ index $sub "_0" }} <#7f849c>| + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} +''' + + [[blocks.segments]] # Hostname + type = 'text' + style = 'plain' + template = '{{ if eq .HostName "server02" }}󰒋 {{.HostName}} <#7f849c>| {{ end }}' + + [[blocks.segments]] # Python venv + type = 'text' + style = 'plain' + template = '{{ if .Env.VIRTUAL_ENV }}🐍 venv <#7f849c>| {{ end }}' + + [[blocks.segments]] # Nix shell indicator + type = 'text' + style = 'plain' + template = '{{ if and .Env.IN_NIX_SHELL (not .Env.DEVSHELL_NAME) }} nsh <#7f849c>| {{ end }}' + + [[blocks.segments]] + template = '{{ .Path }}' + foreground = 'blue' + background = 'transparent' + type = 'path' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' + style = 'full' + + [[blocks.segments]] + template = ' {{ .HEAD }}{{ if or (.Working.Changed) (.Staging.Changed) }} *{{ end }} {{ if gt .Behind 0 }}󰁅{{ end }}{{ if gt .Ahead 0 }}{{ end }}' + foreground = 'green' + background = 'transparent' + type = 'git' + style = 'plain' + + [blocks.segments.properties] + branch_icon = '' + cache_duration = 'none' + commit_icon = '@' + fetch_status = true + +[[blocks]] + type = 'rprompt' + overflow = 'hidden' + + [[blocks.segments]] + template = '{{ .FormattedMs }}' + foreground = 'yellow' + background = 'transparent' + type = 'executiontime' + style = 'plain' + + [blocks.segments.properties] + cache_duration = 'none' + threshold = 5000 + +[[blocks]] + type = 'prompt' + alignment = 'left' + newline = true + + [[blocks.segments]] + template = '❯' + background = 'transparent' + type = 'text' + style = 'plain' + foreground_templates = ['{{if gt .Code 0}}red{{end}}', '{{if eq .Code 0}}magenta{{end}}'] + + [blocks.segments.properties] + cache_duration = 'none' + diff --git a/modules/features/zsh/default.nix b/modules/features/zsh/default.nix new file mode 100644 index 0000000..080336c --- /dev/null +++ b/modules/features/zsh/default.nix @@ -0,0 +1,113 @@ +{ + inputs, + moduleWithSystem, + ... +}: { + flake.nixosModules.zsh = moduleWithSystem ({ + pkgs, + self', + ... + }: { + nixpkgs.overlays = [ + (final: prev: { + zsh = self'.packages.zsh; + }) + ]; + programs.zsh = { + enable = true; + enableCompletion = true; + enableBashCompletion = true; + autosuggestions.enable = true; + syntaxHighlighting.enable = true; + histSize = 10000; + }; + users.defaultUserShell = pkgs.zsh; + }); + perSystem = { + pkgs, + lib, + self', + ... + }: { + packages = { + zsh = let + flakeLocation = builtins.getEnv "PWD"; + in + lib.warnIf (flakeLocation == "") "Flake Location is undefined. Are you building in the right directory?" + inputs.wrappers.wrappers.zsh.wrap { + inherit pkgs; + runtimePkgs = [pkgs.carapace pkgs.devenv pkgs.fzf]; + zshAliases = { + ls = "${lib.getExe pkgs.lsd} -l"; + v = lib.getExe self'.packages.nvim; + cat = lib.getExe pkgs.bat; + lg = lib.getExe pkgs.lazygit; + man = "man -P \"${lib.getExe pkgs.bat} -p\""; + nsh = "nix-shell -p"; + nrs = + if flakeLocation != "" + then "( cd ${flakeLocation} && sudo nixos-rebuild switch --impure --flake . )" + else "echo 'Flake location not specified. Did you build with --impure?'"; + vinix = + if flakeLocation != "" + then "nvim --cmd 'cd ${flakeLocation}'" + else "echo 'Flake location not specified. Did you build with --impure?'"; + }; + zshrc.content = '' + source ${./devenv.zsh} + + if (( ''${+terminfo[smkx]} )) && (( ''${+terminfo[rmkx]} )); then + function zle-line-init() { echoti smkx } + function zle-line-finish() { echoti rmkx } + zle -N zle-line-init + zle -N zle-line-finish + fi + + autoload -U compinit && compinit + export CARAPACE_BRIDGES='zsh,fish,bash,inshellisense' # optional + zstyle ':completion:*' format $'\e[2;37mCompleting %d\e[m' + source <(${lib.getExe pkgs.carapace} _carapace) + zstyle ':completion:*' matcher-list 'm:{[:lower:]}={[:upper:]}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + + autoload -U select-word-style + select-word-style bash + + autoload -U up-line-or-beginning-search down-line-or-beginning-search + zle -N up-line-or-beginning-search + zle -N down-line-or-beginning-search + bindkey "^[OA" up-line-or-beginning-search + bindkey "^[OB" down-line-or-beginning-search + + bindkey "^[[1;5C" forward-word + bindkey "^[[1;5D" backward-word + bindkey "^[[3;5~" kill-word + bindkey "^H" backward-kill-word + + source <(${lib.getExe pkgs.fzf} --zsh) + + setopt NO_CASE_GLOB + + ${lib.getExe pkgs.any-nix-shell} zsh --info-right | source /dev/stdin + + export EDITOR=nvim + + eval "$(${lib.getExe self'.packages.ohMyPosh} init zsh)" + + eval "$(${lib.getExe pkgs.devenv} hook zsh)" + + typeset -ag precmd_functions + if (( ! ''${precmd_functions[(I)__devenv_reload_apply]} )); then + precmd_functions+=(__devenv_reload_apply) + fi + if (( ! ''${precmd_functions[(I)__devenv_restore_path]} )); then + precmd_functions+=(__devenv_restore_path) + fi + ''; + }; + ohMyPosh = inputs.wrappers.wrappers.oh-my-posh.wrap { + inherit pkgs; + configFile = ./config.toml; + }; + }; + }; +} diff --git a/modules/features/zsh/devenv.zsh b/modules/features/zsh/devenv.zsh new file mode 100644 index 0000000..a2e6484 --- /dev/null +++ b/modules/features/zsh/devenv.zsh @@ -0,0 +1,82 @@ +__devenv_reload_apply() { + if [ -n "$DEVENV_RELOAD_FILE" ] && [ -f "$DEVENV_RELOAD_FILE" ]; then + local output + output=$(DEVENV_RELOAD_FILE="$DEVENV_RELOAD_FILE" bash <<'RELOAD_BASH' 2>/dev/null +__devenv_ignored_var() { + case "$1" in + _*|PWD|OLDPWD|SHLVL|SHELL|SHELLOPTS|BASHOPTS|BASH_*|HISTCMD|HISTFILE) + return 0 ;; + PS1|PS2|PS3|PS4|PROMPT|PROMPT_COMMAND|PROMPT_DIRTRIM) + return 0 ;; + COMP_*|READLINE_*|MAILCHECK|COLUMNS|LINES|RANDOM|SECONDS|LINENO|EPOCHSECONDS|EPOCHREALTIME|SRANDOM) + return 0 ;; + STARSHIP_*|__fish*|DIRENV_*|nix_saved_*) + return 0 ;; + *) return 1 ;; + esac +} +__devenv_capture_env() { declare -p -x 2>/dev/null | LC_ALL=C sort; } +__devenv_serialize_diff() { gzip -c | base64 -w0; } +__devenv_deserialize_diff() { echo "$1" | base64 -d | gzip -d 2>/dev/null; } +__devenv_compute_diff() { + local before_file="$1" after_file diff_content + after_file=$(mktemp); diff_content=$(mktemp) + __devenv_capture_env > "$after_file" + local -A before_vars after_vars + while IFS= read -r line; do + [[ "$line" != declare\ -x\ * ]] && continue + local vardef="${line#declare -x }" var="${vardef%%=*}" + [[ -z "$var" ]] && continue + __devenv_ignored_var "$var" && continue + before_vars["$var"]="$line" + done < "$before_file" + while IFS= read -r line; do + [[ "$line" != declare\ -x\ * ]] && continue + local vardef="${line#declare -x }" var="${vardef%%=*}" + [[ -z "$var" ]] && continue + __devenv_ignored_var "$var" && continue + after_vars["$var"]="$line" + done < "$after_file" + for var in "${!before_vars[@]}"; do + [[ "${after_vars[$var]}" != "${before_vars[$var]}" ]] && echo "P:${before_vars[$var]}" >> "$diff_content" + done + for var in "${!after_vars[@]}"; do + if [[ -z "${before_vars[$var]+x}" ]]; then echo "N:$var" >> "$diff_content" + elif [[ "${after_vars[$var]}" != "${before_vars[$var]}" ]]; then echo "N:$var" >> "$diff_content"; fi + done + _DEVENV_DIFF=$(__devenv_serialize_diff < "$diff_content"); export _DEVENV_DIFF + rm -f "$after_file" "$diff_content" +} +__devenv_apply_reverse_diff() { + [[ -z "$_DEVENV_DIFF" ]] && return + local -A prev_vars + local diff_content; diff_content=$(__devenv_deserialize_diff "$_DEVENV_DIFF") + while IFS= read -r line; do + if [[ "$line" == P:declare\ * ]]; then + local decl="${line#P:}" var="${decl#declare -x }"; var="${var%%=*}" + prev_vars["$var"]=1; eval "export ${decl#declare -x }" 2>/dev/null + fi + done <<< "$diff_content" + while IFS= read -r line; do + if [[ "$line" == N:* ]]; then + local var="${line#N:}" + [[ -z "${prev_vars[$var]+x}" ]] && unset "$var" + fi + done <<< "$diff_content" +} +__devenv_apply_reverse_diff +_before=$(mktemp); __devenv_capture_env > "$_before" +if { : >/dev/tty; } 2>/dev/null; then _devenv_reload_out=/dev/tty; else _devenv_reload_out=/dev/null; fi +source "$DEVENV_RELOAD_FILE" >"$_devenv_reload_out" 2>"$_devenv_reload_out" +rm -f "$DEVENV_RELOAD_FILE"; unset _devenv_reload_out +__devenv_compute_diff "$_before"; rm -f "$_before" +export -p +RELOAD_BASH +) + if [ -n "$output" ]; then eval "$output"; fi + _DEVENV_PATH="$PATH" + fi +} +__devenv_restore_path() { + [ -n "$_DEVENV_PATH" ] && export PATH="$_DEVENV_PATH" +} diff --git a/modules/hosts/HACKSTATION/default.nix b/modules/hosts/HACKSTATION/default.nix new file mode 100644 index 0000000..876e39d --- /dev/null +++ b/modules/hosts/HACKSTATION/default.nix @@ -0,0 +1,22 @@ +{ + self, + inputs, + ... +}: { + flake.nixosConfigurations.HACKSTATION = inputs.nixpkgs.lib.nixosSystem { + modules = with self.nixosModules; [ + desktop + hackstationConfiguration + amdDrivers + youtube + development + bottles + gaming + davinci + sddm-autologin + nix-ld + + i3 + ]; + }; +} diff --git a/modules/hosts/HACKSTATION/hackstationConfiguration.nix b/modules/hosts/HACKSTATION/hackstationConfiguration.nix new file mode 100644 index 0000000..2250aa1 --- /dev/null +++ b/modules/hosts/HACKSTATION/hackstationConfiguration.nix @@ -0,0 +1,15 @@ +{...}: { + flake.nixosModules.hackstationConfiguration = {pkgs, ...}: { + virtualisation.docker = { + enable = true; + }; + networking = { + interfaces.enp5s0.wakeOnLan.enable = true; + hostName = "HACKSTATION"; + }; + environment.systemPackages = with pkgs; [ + tor-browser + tor + ]; + }; +} diff --git a/modules/hosts/mobile02/default.nix b/modules/hosts/mobile02/default.nix new file mode 100644 index 0000000..62d3554 --- /dev/null +++ b/modules/hosts/mobile02/default.nix @@ -0,0 +1,15 @@ +{ + self, + inputs, + ... +}: { + flake.nixosConfigurations.mobile02 = inputs.nixpkgs.lib.nixosSystem { + modules = with self.nixosModules; [ + desktop + mobile02Configuration + intelDrivers + development + upower + ]; + }; +} diff --git a/modules/hosts/mobile02/mobile02Configuration.nix b/modules/hosts/mobile02/mobile02Configuration.nix new file mode 100644 index 0000000..f67ec8f --- /dev/null +++ b/modules/hosts/mobile02/mobile02Configuration.nix @@ -0,0 +1,11 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.mobile02Configuration = {...}: { + networking = { + hostName = "mobile02"; + }; + }; +} diff --git a/modules/i3/i3.nix b/modules/i3/i3.nix deleted file mode 100644 index 01e1d0d..0000000 --- a/modules/i3/i3.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - config, - lib, - pkgs, - inputs, - ... -}: { - services.libinput.enable = true; - - services.displayManager.defaultSession = "hyprland"; - services.xserver = { - enable = true; - - desktopManager = { - xterm.enable = false; - }; - - windowManager.i3 = { - enable = true; - extraPackages = with pkgs; [ - dmenu # application launcher most people use - i3status # gives you the default i3 status bar - xinit - ]; - }; - }; -} diff --git a/modules/parts.nix b/modules/parts.nix new file mode 100644 index 0000000..657e3ca --- /dev/null +++ b/modules/parts.nix @@ -0,0 +1,10 @@ +{ + config = { + systems = [ + "x86_64-linux" + "x86_64-darwin" + "aarch64-linux" + "aarch64-darwin" + ]; + }; +} diff --git a/modules/system/audio/default.nix b/modules/system/audio/default.nix new file mode 100644 index 0000000..021835d --- /dev/null +++ b/modules/system/audio/default.nix @@ -0,0 +1,29 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.audio = { + pkgs, + lib, + ... + }: { + environment.systemPackages = with pkgs; [ + playerctl + pavucontrol + pulseaudioFull + ]; + services.pulseaudio.enable = false; + security.rtkit.enable = true; + + nixpkgs.config.pulseaudio = true; + + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; + }; +} diff --git a/modules/system/core/boot.nix b/modules/system/core/boot.nix new file mode 100644 index 0000000..4ea3e94 --- /dev/null +++ b/modules/system/core/boot.nix @@ -0,0 +1,36 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.bootloader = { + pkgs, + lib, + ... + }: { + boot = { + loader = { + timeout = 2; + efi = { + canTouchEfiVariables = true; + }; + grub = { + efiSupport = true; + device = "nodev"; + theme = pkgs.catppuccin-grub; + }; + }; + plymouth = { + enable = true; + theme = "catppuccin-mocha"; + themePackages = with pkgs; [ + # By default we would install all themes + (catppuccin-plymouth.override { + variant = "mocha"; + }) + ]; + }; + kernelPackages = pkgs.linuxPackages_latest; + }; + }; +} diff --git a/modules/system/core/default.nix b/modules/system/core/default.nix new file mode 100644 index 0000000..d2ec884 --- /dev/null +++ b/modules/system/core/default.nix @@ -0,0 +1,42 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.core = { + pkgs, + lib, + ... + }: let + modules = with self.nixosModules; [ + user + bootloader + nix + hardware + locale + ]; + in { + imports = + [ + /etc/nixos/hardware-configuration.nix + ] + ++ modules; + services = { + openssh.enable = true; + avahi.enable = true; + }; + environment.systemPackages = with pkgs; [ + vim + unzip + p7zip-rar + usbutils + lsof + gvfs + libnotify + python315 + curlWithGnuTls + wget + ]; + system.stateVersion = "25.05"; + }; +} diff --git a/modules/system/core/hardware.nix b/modules/system/core/hardware.nix new file mode 100644 index 0000000..ea931b8 --- /dev/null +++ b/modules/system/core/hardware.nix @@ -0,0 +1,16 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.hardware = { + pkgs, + lib, + ... + }: { + hardware = { + bluetooth.enable = true; + xpadneo.enable = true; + }; + }; +} diff --git a/modules/system/core/locale.nix b/modules/system/core/locale.nix new file mode 100644 index 0000000..df67371 --- /dev/null +++ b/modules/system/core/locale.nix @@ -0,0 +1,32 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.locale = { + pkgs, + lib, + ... + }: { + time.timeZone = "Europe/London"; + i18n = { + defaultLocale = "en_GB.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "en_GB.UTF-8"; + LC_IDENTIFICATION = "en_GB.UTF-8"; + LC_MEASUREMENT = "en_GB.UTF-8"; + LC_MONETARY = "en_GB.UTF-8"; + LC_NAME = "en_GB.UTF-8"; + LC_NUMERIC = "en_GB.UTF-8"; + LC_PAPER = "en_GB.UTF-8"; + LC_TELEPHONE = "en_GB.UTF-8"; + LC_TIME = "en_GB.UTF-8"; + }; + }; + services.xserver.xkb = { + layout = "gb"; + variant = ""; + }; + console.keyMap = "uk"; + }; +} diff --git a/modules/system/core/nix-settings.nix b/modules/system/core/nix-settings.nix new file mode 100644 index 0000000..ad2fb4c --- /dev/null +++ b/modules/system/core/nix-settings.nix @@ -0,0 +1,52 @@ +{inputs, ...}: { + perSystem = {system, ...}: { + _module.args.unfreePkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + }; + }; + flake.nixosModules.nix = {...}: { + nix = { + registry = { + voidarc = { + from = { + id = "voidarc"; + type = "indirect"; + }; + to = { + type = "git"; + url = "https://git.voidarc.co.uk/voidarc/flakes.git"; + }; + }; + }; + settings = { + cores = 6; + trusted-users = ["root" "user01"]; + download-buffer-size = 524288000; + experimental-features = [ + "nix-command" + "flakes" + ]; + }; + nixPath = ["nixpkgs=${inputs.nixpkgs}"]; + optimise.automatic = true; + gc = { + automatic = true; + dates = "daily"; + options = "--delete-older-than 5d"; + }; + }; + nixpkgs = { + config = { + allowUnfree = true; + packageOverrides = pkgs: { + unstable = import inputs.nixpkgs-unstable { + config = { + allowUnfree = true; + }; + }; + }; + }; + }; + }; +} diff --git a/modules/system/core/user.nix b/modules/system/core/user.nix new file mode 100644 index 0000000..58174bb --- /dev/null +++ b/modules/system/core/user.nix @@ -0,0 +1,27 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.user = { + pkgs, + lib, + ... + }: let + modules = with self.nixosModules; [ + zsh + ]; + in { + imports = modules; + users.users.user01 = { + isNormalUser = true; + initialPassword = "qwer"; + shell = pkgs.zsh; + description = "user01"; + extraGroups = [ + "root" + "wheel" + ]; + }; + }; +} diff --git a/modules/system/desktop/default.nix b/modules/system/desktop/default.nix new file mode 100644 index 0000000..b0dfcee --- /dev/null +++ b/modules/system/desktop/default.nix @@ -0,0 +1,21 @@ +{ + self, + moduleWithSystem, + ... +}: { + flake.nixosModules.desktop = moduleWithSystem ({pkgs, ...}: let + modules = with self.nixosModules; [ + core + hyprland + sddm + network + omnisearch + tailscale + ]; + in { + imports = modules; + environment.systemPackages = with pkgs; [ + mpv + ]; + }); +} diff --git a/modules/system/drivers/amd.nix b/modules/system/drivers/amd.nix new file mode 100644 index 0000000..895bd68 --- /dev/null +++ b/modules/system/drivers/amd.nix @@ -0,0 +1,34 @@ +{...}: { + flake.nixosModules.amdDrivers = {pkgs, ...}: { + environment.systemPackages = with pkgs; [ + mesa + rocmPackages.rocm-smi + rocmPackages.rocminfo + vulkan-tools + ]; + hardware = { + graphics = { + enable = true; + enable32Bit = true; + extraPackages = with pkgs; [ + libva-vdpau-driver + libvdpau-va-gl + rocmPackages.clr.icd + ]; + }; + amdgpu = { + initrd.enable = true; + opencl.enable = true; + }; + }; + + boot.kernelParams = [ + "amdgpu.ppfeaturemask=0xffffffff" + ]; + + # For rOCM + systemd.tmpfiles.rules = [ + "L+ /opt/rocm - - - - ${pkgs.rocmPackages.clr}" + ]; + }; +} diff --git a/modules/system/drivers/intel.nix b/modules/system/drivers/intel.nix new file mode 100644 index 0000000..54be043 --- /dev/null +++ b/modules/system/drivers/intel.nix @@ -0,0 +1,23 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.intelDrivers = { + pkgs, + lib, + ... + }: { + environment.systemPackages = with pkgs; [ + mesa + vulkan-tools + ]; + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ + intel-vaapi-driver + libva-vdpau-driver + ]; + }; + }; +} diff --git a/modules/system/drivers/upower.nix b/modules/system/drivers/upower.nix new file mode 100644 index 0000000..38d6377 --- /dev/null +++ b/modules/system/drivers/upower.nix @@ -0,0 +1,11 @@ +{...}: { + flake.nixosModules.upower = {pkgs, ...}: { + environment.systemPackages = with pkgs; [ + upower + ]; + services = { + upower.enable = true; + power-profiles-daemon.enable = true; + }; + }; +} diff --git a/modules/system/network/default.nix b/modules/system/network/default.nix new file mode 100644 index 0000000..05c041d --- /dev/null +++ b/modules/system/network/default.nix @@ -0,0 +1,28 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.network = { + pkgs, + lib, + ... + }: { + networking = { + networkmanager = { + enable = true; + dns = "none"; + }; + nameservers = [ + "1.1.1.1" + "8.8.8.8" + ]; + firewall.enable = false; + }; + services.unbound = { + enable = true; + }; + + systemd.services.NetworkManager-wait-online.enable = false; + }; +} diff --git a/modules/system/nix-ld/default.nix b/modules/system/nix-ld/default.nix new file mode 100644 index 0000000..ee7b70f --- /dev/null +++ b/modules/system/nix-ld/default.nix @@ -0,0 +1,15 @@ +{moduleWithSystem, ...}: { + flake.nixosModules.nix-ld = moduleWithSystem ({pkgs, ...}: { + programs = { + nix-ld = { + enable = true; + libraries = with pkgs; [ + util-linux + stdenv.cc.cc + zlib + libusb1 + ]; + }; + }; + }); +} diff --git a/modules/system/systemTheme/cursor.nix b/modules/system/systemTheme/cursor.nix new file mode 100644 index 0000000..d453379 --- /dev/null +++ b/modules/system/systemTheme/cursor.nix @@ -0,0 +1,36 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.bibataCursors = { + pkgs, + lib, + ... + }: let + in { + fonts.packages = with pkgs.nerd-fonts; [ + fira-mono + ]; + environment.systemPackages = with pkgs; [ + bibata-cursors + ]; + + environment.variables = { + XCURSOR_THEME = "Bibata-Modern-Ice"; + XCURSOR_SIZE = "20"; + }; + + programs.dconf.profiles.user.databases = [ + { + lockAll = false; + settings = { + "org/gnome/desktop/interface" = { + cursor-theme = "Bibata-Modern-Ice"; + font-name = "FiraMono Nerd Font 11"; + }; + }; + } + ]; + }; +} diff --git a/modules/system/systemTheme/default.nix b/modules/system/systemTheme/default.nix new file mode 100644 index 0000000..3957fba --- /dev/null +++ b/modules/system/systemTheme/default.nix @@ -0,0 +1,19 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.systemTheme = { + config, + pkgs, + lib, + ... + }: let + modules = with self.nixosModules; [ + bibataCursors + catppuccinGtk + ]; + in { + imports = modules; + }; +} diff --git a/modules/system/systemTheme/gtk.nix b/modules/system/systemTheme/gtk.nix new file mode 100644 index 0000000..d26f2e9 --- /dev/null +++ b/modules/system/systemTheme/gtk.nix @@ -0,0 +1,43 @@ +{ + self, + inputs, + ... +}: { + flake.nixosModules.catppuccinGtk = { + pkgs, + lib, + ... + }: let + in { + environment.systemPackages = with pkgs; [ + (catppuccin-gtk.override { + variant = "mocha"; + accents = ["mauve"]; + tweaks = ["rimless"]; + size = "compact"; + }) + (catppuccin-papirus-folders.override { + flavor = "mocha"; + accent = "mauve"; + }) + ]; + programs = { + xfconf.enable = true; + dconf = { + enable = true; + profiles.user.databases = [ + { + lockAll = false; + settings = { + "org/gnome/desktop/interface" = { + gtk-theme = "catppuccin-mocha-mauve-compact+rimless"; + icon-theme = "Papirus"; + color-scheme = "prefer-dark"; + }; + }; + } + ]; + }; + }; + }; +}