diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..c880469 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,8 @@ +keys: + - &cyper-desktop age10pyhca0jy75wtqv5hrn0gf0jcam5272zx9h73a8xwwaxyfq89c0qs5dr9t + +creation_rules: + - path_regex: secrets/.* + key_groups: + - age: + - *cyper-desktop diff --git a/README.md b/README.md index e69de29..db5f2c4 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,94 @@ +# Nix macOS Starter + +A beginner-friendly Nix configuration for macOS using flakes, nix-darwin, Home Manager, and Mise. + +## About + +A clean, well-documented starting point for managing your macOS system declaratively with Nix. Includes sensible defaults for development tools, shell configuration, and system settings. + +**Author:** Ben Gubler + +## Prerequisites + +1. **Install Nix** using the [Determinate Systems installer](https://docs.determinate.systems/#products) (download the graphical installer for macOS). After installation, restart your terminal. + +**Note:** Homebrew is managed declaratively via nix-homebrew - if you already have it installed, it will auto-migrate. Otherwise, it's installed automatically. + +## Quick Start + +### 1. Clone and Configure + +```bash +# Clone the repository +git clone https://github.com/nebrelbug/nix-macos-starter ~/.config/nix +cd ~/.config/nix +``` + +### 2. Customize Your Configuration + +**For Intel Mac Users:** Change the system architecture in `flake.nix` from `"aarch64-darwin"` to `"x86_64-darwin"` on line 28. + +**Replace all placeholders:** + +- `flake.nix`: `YOUR_USERNAME` (this sets the username for the entire system) +- `home/git.nix`: `YOUR_NAME`, `YOUR_EMAIL` + +### 3. Apply the Configuration + +```bash +# Build and switch to the configuration +darwin-rebuild switch --flake .#my-macbook + +# Or use the alias after initial setup +nix-switch +``` + +## What's Included + +**Development Tools**: [mise](https://mise.jdx.dev/) for Node.js/Python/Rust/etc., Zsh with Starship prompt, essential CLI tools (curl, vim, tmux, htop, tree, ripgrep, gh, zoxide), code quality tools (nil, biome, nixfmt-rfc-style) + +**GUI Applications**: Cursor, Ghostty, VS Code, Zed, Raycast, CleanShot, HiddenBar, BetterDisplay, Discord, Slack, 1Password, Brave Browser, Obsidian, Spotify + +**System Configuration**: Git setup, macOS optimizations (Finder, Touch ID sudo), Nix settings (flakes, garbage collection), declarative Homebrew management + +## Project Structure + +``` +nix-macos-starter/ +├── flake.nix # Main flake configuration and inputs +├── darwin/ +│ ├── default.nix # Core macOS system configuration +│ ├── settings.nix # macOS UI/UX preferences and defaults +│ └── homebrew.nix # GUI applications via Homebrew +├── home/ +│ ├── default.nix # Home Manager configuration entry point +│ ├── packages.nix # Package declarations and mise setup +│ ├── git.nix # Git configuration +│ ├── shell.nix # Shell configuration +│ └── mise.nix # Development runtime management +└── hosts/ + └── my-macbook/ + ├── configuration.nix # Host-specific packages and settings + └── shell-functions.sh # Custom shell scripts +``` + +## Customization + +**Add CLI Tools**: Edit `home/packages.nix` packages array +**Add GUI Apps**: Edit `darwin/homebrew.nix` casks array +**Add Development Tools**: Add `${pkgs.mise}/bin/mise use --global tool@version` to `home/mise.nix` activation script +**Host-Specific Config**: Use `hosts/my-macbook/configuration.nix` for machine-specific packages/apps and `custom-scripts.sh` for shell scripts + +## Troubleshooting + +**"Command not found"**: Restart terminal +**Permission denied**: Use `sudo darwin-rebuild switch --flake .#my-macbook` +**Homebrew apps not installing**: nix-homebrew handles this automatically; ensure `/opt/homebrew/bin` in PATH +**Git config not applying**: Replace all `YOUR_*` placeholders, re-run darwin-rebuild + +**Need help?** Check [Nix manual](https://nixos.org/manual/nix/stable/), [nix-darwin docs](https://github.com/LnL7/nix-darwin), [Home Manager options](https://nix-community.github.io/home-manager/options.html) + +## Credits + +- [Ethan Niser](https://github.com/ethanniser) for his [config repo](https://github.com/ethanniser/config) which I used as a reference for this project. +- David Haupt's excellent [tutorial series](https://davi.sh/blog/2024/01/nix-darwin/) which (although slightly outdated) helped me understand the basics of Nix. diff --git a/assets/avatar/avatar.png b/assets/avatar/avatar.png new file mode 100644 index 0000000..518b5fe Binary files /dev/null and b/assets/avatar/avatar.png differ diff --git a/assets/avatar/avatar_high.png b/assets/avatar/avatar_high.png new file mode 100644 index 0000000..62a5b68 Binary files /dev/null and b/assets/avatar/avatar_high.png differ diff --git a/assets/avatar/avatar_no_bg.png b/assets/avatar/avatar_no_bg.png new file mode 100644 index 0000000..0858bf4 Binary files /dev/null and b/assets/avatar/avatar_no_bg.png differ diff --git a/assets/avatar/avatar_sloth.png b/assets/avatar/avatar_sloth.png new file mode 100644 index 0000000..9563e3b Binary files /dev/null and b/assets/avatar/avatar_sloth.png differ diff --git a/assets/avatar/avatar_sloth_no_bg.png b/assets/avatar/avatar_sloth_no_bg.png new file mode 100644 index 0000000..82a97d0 Binary files /dev/null and b/assets/avatar/avatar_sloth_no_bg.png differ diff --git a/assets/avatar/avatar_talking.gif b/assets/avatar/avatar_talking.gif new file mode 100644 index 0000000..3a61e52 Binary files /dev/null and b/assets/avatar/avatar_talking.gif differ diff --git a/assets/avatar/avatar_talking.mp4 b/assets/avatar/avatar_talking.mp4 new file mode 100644 index 0000000..df0a358 Binary files /dev/null and b/assets/avatar/avatar_talking.mp4 differ diff --git a/assets/avatar/avatar_talking_no_bg.gif b/assets/avatar/avatar_talking_no_bg.gif new file mode 100644 index 0000000..baec78d Binary files /dev/null and b/assets/avatar/avatar_talking_no_bg.gif differ diff --git a/assets/avatar/avatar_talking_no_bg.mp4 b/assets/avatar/avatar_talking_no_bg.mp4 new file mode 100644 index 0000000..d79d514 Binary files /dev/null and b/assets/avatar/avatar_talking_no_bg.mp4 differ diff --git a/assets/avatar/avatar_weather.png b/assets/avatar/avatar_weather.png new file mode 100644 index 0000000..5f6e018 Binary files /dev/null and b/assets/avatar/avatar_weather.png differ diff --git a/assets/avatar/avatar_weather_no_bg.png b/assets/avatar/avatar_weather_no_bg.png new file mode 100644 index 0000000..b5d5f5a Binary files /dev/null and b/assets/avatar/avatar_weather_no_bg.png differ diff --git a/assets/wallpapers/Ghost_in_the_Shell.png b/assets/wallpapers/Ghost_in_the_Shell.png new file mode 100644 index 0000000..a79762b Binary files /dev/null and b/assets/wallpapers/Ghost_in_the_Shell.png differ diff --git a/assets/wallpapers/Helicopter.png b/assets/wallpapers/Helicopter.png new file mode 100644 index 0000000..722acb6 Binary files /dev/null and b/assets/wallpapers/Helicopter.png differ diff --git a/assets/wallpapers/Major.png b/assets/wallpapers/Major.png new file mode 100644 index 0000000..5c19413 Binary files /dev/null and b/assets/wallpapers/Major.png differ diff --git a/assets/wallpapers/bike.gif b/assets/wallpapers/bike.gif new file mode 100644 index 0000000..b1bac42 Binary files /dev/null and b/assets/wallpapers/bike.gif differ diff --git a/assets/wallpapers/corner.gif b/assets/wallpapers/corner.gif new file mode 100644 index 0000000..17dd259 Binary files /dev/null and b/assets/wallpapers/corner.gif differ diff --git a/assets/wallpapers/daemon.gif b/assets/wallpapers/daemon.gif new file mode 100644 index 0000000..ea7f656 Binary files /dev/null and b/assets/wallpapers/daemon.gif differ diff --git a/assets/wallpapers/daemon_layer.png b/assets/wallpapers/daemon_layer.png new file mode 100644 index 0000000..3fe0704 Binary files /dev/null and b/assets/wallpapers/daemon_layer.png differ diff --git a/assets/wallpapers/dead_cyborg.png b/assets/wallpapers/dead_cyborg.png new file mode 100644 index 0000000..6f98008 Binary files /dev/null and b/assets/wallpapers/dead_cyborg.png differ diff --git a/assets/wallpapers/dna.gif b/assets/wallpapers/dna.gif new file mode 100644 index 0000000..54ac650 Binary files /dev/null and b/assets/wallpapers/dna.gif differ diff --git a/assets/wallpapers/ghost.gif b/assets/wallpapers/ghost.gif new file mode 100644 index 0000000..a76e324 Binary files /dev/null and b/assets/wallpapers/ghost.gif differ diff --git a/assets/wallpapers/girl.png b/assets/wallpapers/girl.png new file mode 100644 index 0000000..bffdb87 Binary files /dev/null and b/assets/wallpapers/girl.png differ diff --git a/assets/wallpapers/girl_nixos.png b/assets/wallpapers/girl_nixos.png new file mode 100644 index 0000000..d50cb50 Binary files /dev/null and b/assets/wallpapers/girl_nixos.png differ diff --git a/assets/wallpapers/lucy.png b/assets/wallpapers/lucy.png new file mode 100644 index 0000000..8d52048 Binary files /dev/null and b/assets/wallpapers/lucy.png differ diff --git a/assets/wallpapers/lucy_with_cat.png b/assets/wallpapers/lucy_with_cat.png new file mode 100644 index 0000000..9910901 Binary files /dev/null and b/assets/wallpapers/lucy_with_cat.png differ diff --git a/assets/wallpapers/rain.gif b/assets/wallpapers/rain.gif new file mode 100644 index 0000000..8299cea Binary files /dev/null and b/assets/wallpapers/rain.gif differ diff --git a/assets/wallpapers/space_station.png b/assets/wallpapers/space_station.png new file mode 100644 index 0000000..045556c Binary files /dev/null and b/assets/wallpapers/space_station.png differ diff --git a/assets/wallpapers/tokio.png b/assets/wallpapers/tokio.png new file mode 100644 index 0000000..7137c0a Binary files /dev/null and b/assets/wallpapers/tokio.png differ diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..5538a67 --- /dev/null +++ b/flake.lock @@ -0,0 +1,314 @@ +{ + "nodes": { + "brew-src": { + "flake": false, + "locked": { + "lastModified": 1749511373, + "narHash": "sha256-7u1TdHQaUCzzgf/n8T3bQosuYXyNBEPU/3WQQqozE5o=", + "owner": "Homebrew", + "repo": "brew", + "rev": "7b4ef99fed96966269ee35994407fa4c06097a4d", + "type": "github" + }, + "original": { + "owner": "Homebrew", + "ref": "4.5.6", + "repo": "brew", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1751313918, + "narHash": "sha256-HsJM3XLa43WpG+665aGEh8iS8AfEwOIQWk3Mke3e7nk=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "e04a388232d9a6ba56967ce5b53a8a6f713cdfcf", + "type": "github" + }, + "original": { + "owner": "lnl7", + "repo": "nix-darwin", + "type": "github" + } + }, + "flake-compat": { + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "revCount": 69, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz?rev=ff81ac966bb2cae68946d5ed5fc4994f96d0ffec&revCount=69" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1763759067, + "narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765835352, + "narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "a34fae9c08a15ad73f295041fec82323541400a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1752093218, + "narHash": "sha256-+3rXu8ewcNDi65/2mKkdSGrivQs5zEZVp5aYszXC0d0=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "206ed3c71418b52e176f16f58805c96e84555320", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "nix-homebrew": { + "inputs": { + "brew-src": "brew-src" + }, + "locked": { + "lastModified": 1749952250, + "narHash": "sha256-V2ix0knpdJXirQ+4pjbnggjdSALTsFWGIP/NDpaQkdU=", + "owner": "zhaofengli", + "repo": "nix-homebrew", + "rev": "37126f06f4890f019af3d7606ce5d30a457afcd0", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "repo": "nix-homebrew", + "type": "github" + } + }, + "nixcord": { + "inputs": { + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1766917993, + "narHash": "sha256-Hf5T3qQX4hgGQITFSCqsIorMo0FxcI4TsygB1iruUeU=", + "owner": "kaylorben", + "repo": "nixcord", + "rev": "63871baa87897231803d617eab908261caa5907c", + "type": "github" + }, + "original": { + "owner": "kaylorben", + "repo": "nixcord", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1766201043, + "narHash": "sha256-eplAP+rorKKd0gNjV3rA6+0WMzb1X1i16F5m5pASnjA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b3aad468604d3e488d627c0b43984eb60e75e782", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1761765539, + "narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "719359f4562934ae99f5443f20aa06c2ffff91fc", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1751949589, + "narHash": "sha256-mgFxAPLWw0Kq+C8P3dRrZrOYEQXOtKuYVlo9xvPntt8=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9b008d60392981ad674e04016d25619281550a9d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1766653575, + "narHash": "sha256-TPgxCS7+hWc4kPhzkU5dD2M5UuPhLuuaMNZ/IpwKQvI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3c1016e6acd16ad96053116d0d3043029c9e2649", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1766651565, + "narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixvim": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_3", + "systems": "systems" + }, + "locked": { + "lastModified": 1766604046, + "narHash": "sha256-9Wvp2G/z0YYMn7oeN/E90pRtXJxQCo7EZrKKkNpwru4=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "48b23bdae0770d86e1d0cb8ed830a0cb58810333", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "root": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nix-homebrew": "nix-homebrew", + "nixcord": "nixcord", + "nixpkgs": "nixpkgs_2", + "nixvim": "nixvim", + "spicetify-nix": "spicetify-nix" + } + }, + "spicetify-nix": { + "inputs": { + "nixpkgs": "nixpkgs_4", + "systems": "systems_2" + }, + "locked": { + "lastModified": 1766897356, + "narHash": "sha256-oKp9luuuXuMoUwpGUKUdt0G7lZGovcyOEI3guG0rNCw=", + "owner": "Gerg-L", + "repo": "spicetify-nix", + "rev": "6b49c4094e93629af2fcf789e0897450f57e2551", + "type": "github" + }, + "original": { + "owner": "Gerg-L", + "repo": "spicetify-nix", + "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" + } + }, + "systems_2": { + "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..7ff6abf --- /dev/null +++ b/flake.nix @@ -0,0 +1,88 @@ +{ + description = "Nix Desktop Configuration"; + + inputs = { + # monorepo w/ recipes ("derivations") + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + # declarative Configs + home-manager = { + url = "github:nix-community/home-manager/main"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Hyprland + hyprland = { + url = "github:hyprwm/Hyprland"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + hyprland-plugins = { + url = "github:hyprwm/hyprland-plugins"; + inputs.hyprland.follows = "hyprland"; + }; + + hyprcursor = { + url = "github:hyprwm/hyprcursor"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Neovim + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Discord + nixcord = { + url = "github:kaylorben/nixcord"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Spotify + spicetify-nix = { + url = "github:Gerg-L/spicetify-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Encryption + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # declarative Catppuccin + catppuccin = { + url = "github:catppuccin/nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { + self, + nixpkgs, + home-manager, + nixvim, + hyprland, + sops-nix, + ... + }@inputs: + let + primaryUser = "phil"; + in + { + # $ nixos-rebuild switch --flake .# + nixosConfigurations."cyper-desktop" = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ./nixos + ./hosts/cyper-desktop/configuration.nix + inputs.home-manager.nixosModules.home-manager + inputs.sops-nix.nixosModules.sops + ]; + specialArgs = { inherit inputs primaryUser; }; + }; + + }; +} diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..ce62b29 --- /dev/null +++ b/home/default.nix @@ -0,0 +1,56 @@ +{ + config, + primaryUser, + inputs, + ... +}: +{ + imports = [ + + ./packages.nix + ./git.nix + ./shell.nix + ./xdg.nix + + inputs.nixvim.homeModules.nixvim + ./neovim + ./python.nix + + inputs.nixcord.homeModules.nixcord + ./nixcord.nix + + inputs.spicetify-nix.homeManagerModules.default + ./spicetify.nix + + ./floorp.nix + ./obsidian.nix + + inputs.catppuccin.homeManagerModules.catppuccin + ./desktop + ]; + + catppuccin = { + enable = true; + flavor = "mocha"; + }; + + home = { + username = primaryUser; + stateVersion = "25.11"; + sessionVariables = { + GROQ_API_KEY = config.sops.secrets.GROQ_API_KEY.path; + }; + + file = { + "Pictures/Avatar" = { + source = ../assets/avatar; + recursive = true; + }; + + "Pictures/Wallpapers" = { + source = ../assets/wallpapers; + recursive = true; + }; + }; + }; +} diff --git a/home/desktop/default.nix b/home/desktop/default.nix new file mode 100644 index 0000000..10a4081 --- /dev/null +++ b/home/desktop/default.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + imports = [ + ./hyprland + ./rofi + ./waybar + ./gtk.nix + ./qt.nix + ]; + + _module.args.compositor = "hyprland"; + + home = { + packages = with pkgs; [ + waypaper + swww + ]; + file.".config/waypaper/config.ini".source = ./waypaper.ini; + }; +} diff --git a/home/desktop/gtk.nix b/home/desktop/gtk.nix new file mode 100644 index 0000000..61ad6f6 --- /dev/null +++ b/home/desktop/gtk.nix @@ -0,0 +1,32 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ catppuccin-papirus-folders ]; + + gtk = { + enable = true; + + font = { + name = "FiraCode Nerd Font Propo"; + size = 12; + }; + + theme = { + name = "catppuccin-mocha-standard-mauve-dark"; + package = pkgs.catppuccin-gtk; + }; + + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + + cursorTheme = { + name = "catppuccin-mocha-dark"; + package = pkgs.catppuccin-cursors.mocha-dark; + size = 24; + }; + + gtk3.extraConfig.gtk-application-prefer-dark-theme = true; + gtk4.extraConfig.gtk-application-prefer-dark-theme = true; + }; +} diff --git a/home/desktop/hyprland/default.nix b/home/desktop/hyprland/default.nix new file mode 100644 index 0000000..51ba27a --- /dev/null +++ b/home/desktop/hyprland/default.nix @@ -0,0 +1,293 @@ +{ inputs, pkgs, ... }: +let + package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland; + super = "SUPER"; + terminal = "kitty"; + fileManager = "yazi"; + theme = "-theme $HOME/.config/rofi/custom.rasi"; + menu = "rofi -show drun ${theme}"; + filebrowser = "rofi -show filebrowser ${theme}"; + power = "rofi -show p -modi p:rofi-power-menu -theme $HOME/.config/rofi/power.rasi"; + apps = "rofi -show window ${theme}"; +in +{ + + imports = [ + ./hypridle.nix + ./hyprlock.nix + ./mako.nix + ./portal.nix + ]; + + home.packages = with pkgs; [ + catppuccin-cursors.mocha-dark + grim + slurp + wl-clipboard + ]; + + systemd.user.targets.hyprland-session.Unit.Wants = [ + "xdg-desktop-autostart.target" + ]; + + wayland.windowManager.hyprland = { + inherit package; + enable = true; + + xwayland.enable = true; + + systemd = { + enable = true; + variables = [ "--all" ]; + enableXdgAutostart = false; + }; + + plugins = with inputs.hyprland-plugins.packages.${pkgs.stdenv.hostPlatform.system}; [ + hyprbars + hyprexpo + ]; + + settings = { + env = [ + "NIXOS_OZONE_WL,1" + "MOZ_ENABLE_WAYLAND,1" + "MOZ_WEBRENDER,1" + "_JAVA_AWT_WM_NONREPARENTING,1" + "QT_WAYLAND_DISABLE_WINDOWDECORATION,1" + "QT_QPA_PLATFORM,wayland" + "SDL_VIDEODRIVER,wayland" + "GDK_BACKEND,wayland,x11" + "XCURSOR_SIZE,24" + "EDITOR,nvim" + "GSK_RENDERER,gl" + "HYPRCURSOR_THEME,catppuccin-mocha-dark" + "HYPRCURSOR_SIZE,24" + "XCURSOR_THEME,catppuccin-mocha-dark" + "XCURSOR_SIZE,24" + ]; + + monitor = [ + "DP-1, 1920x1080@60, 1920x0, 1" + "HDMI-A-2, 1920x1080@60, 0x0, 1" + ]; + + input = { + kb_layout = "de"; + kb_variant = "mac"; + repeat_rate = 50; + repeat_delay = 300; + + accel_profile = "flat"; + follow_mouse = 1; + mouse_refocus = false; + sensitivity = 0; # -1.0 to 1.0, 0 means no modification. + + numlock_by_default = 1; + touchpad = { + natural_scroll = true; + tap-to-click = true; + }; + + }; + + general = { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + gaps_in = 4; + gaps_out = 0; + border_size = 4; + + "col.active_border" = "$green"; + "col.inactive_border" = "$red"; + + layout = "dwindle"; + + # Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on + allow_tearing = false; + }; + + decoration = { + rounding = 1; + + shadow = { + enabled = false; + range = 16; + render_power = 4; + ignore_window = true; + color = "$green"; + color_inactive = "$red"; + }; + + blur = { + enabled = false; + size = 1; + passes = 3; + new_optimizations = 1; + noise = 0.04; + }; + }; + + animations = { + enabled = "yes"; + bezier = "myBezier, 0.05, 0.9, 0.1, 1.05"; + animation = [ + "windows, 1, 7, myBezier" + "windowsOut, 1, 7, default, popin 80%" + "border, 1, 10, default" + "borderangle, 1, 8, default" + "fade, 1, 7, default" + "workspaces, 1, 6, default" + ]; + }; + + layerrule = [ + "ignorezero,notifications" + "ignorezero,rofi" + ]; + + dwindle = { + pseudotile = "yes"; + preserve_split = "yes"; + }; + + gestures = { + # See https://wiki.hyprland.org/Configuring/Variables/ for more + workspace_swipe = true; + workspace_swipe_fingers = 3; + workspace_swipe_distance = 300; + workspace_swipe_invert = false; + workspace_swipe_cancel_ratio = 0.5; + }; + + misc = { + force_default_wallpaper = 0; + disable_hyprland_logo = true; + disable_splash_rendering = true; + mouse_move_enables_dpms = true; + key_press_enables_dpms = true; + vfr = true; + vrr = 0; + }; + + device = { + name = "usb-optical-mouse-"; + sensitivity = -0.5; + }; + + windowrulev2 = [ + "suppressevent maximize, class:.*" + "float, class:^(com.obsproject.Studio)$" + "size 1280 800, class:^(com.obsproject.Studio)$" + "float, class:^(xdg-desktop-portal-gtk)$" + "center, class:^(xdg-desktop-portal-gtk)$" + ]; + + windowrule = [ + "opacity 0.0 override, class:^(xwaylandvideobridge)$" + "noanim, class:^(xwaylandvideobridge)$" + "noinitialfocus, class:^(xwaylandvideobridge)$" + "maxsize 1 1, class:^(xwaylandvideobridge)$" + "noblur, class:^(xwaylandvideobridge)$" + "nofocus, class:^(xwaylandvideobridge)$" + "noblur, class:^(org\\.gnome\\.|io\\.github\\.|org\\.gtk\\.)" + ]; + + exec-once = [ + "waybar &" + "swww-daemon & disown" + ]; + + # Keybindings + bind = [ + + # Application Bindings + "${super}, Q, exec, ${terminal}" + "${super}, E, exec, ${fileManager}" + "${super}, O, exec, obsidian" + "${super}, I, exec, floorp" + "${super}, G, exec, thunderbird" + "${super}, N, exec, nautilus" + + # Lock Screen + "${super}, M, exit, " + + # swaync + "${super}, Y, exec, swaync-client -t -sw" + + # Rofi bindings + "${super}, F, exec, ${filebrowser}" + "${super}, A, exec, ${apps}" + "${super}, R, exec, ${menu}" + "${super}, S, exec, ${power}" + + # Move focus with mainMod + arrow keys + "${super}, left, movefocus, l" + "${super}, right, movefocus, r" + "${super}, up, movefocus, u" + "${super}, down, movefocus, d" + + # Window Modifiers + "${super}, P, pseudo, " # dwindle + "${super}, J, togglesplit, " # dwindle + "${super}, V, togglefloating, " # dwindle + "${super}, C, killactive, " + + # Switch workspaces with mainMod + [0-9] + "${super}, 1, workspace, 1" + "${super}, 2, workspace, 2" + "${super}, 3, workspace, 3" + "${super}, 4, workspace, 4" + "${super}, 5, workspace, 5" + "${super}, 6, workspace, 6" + "${super}, 7, workspace, 7" + "${super}, 8, workspace, 8" + "${super}, 9, workspace, 9" + "${super}, 0, workspace, 10" + + # Move active window to a workspace with mainMod + SHIFT + [0-9] + "${super} SHIFT, 1, movetoworkspace, 1" + "${super} SHIFT, 2, movetoworkspace, 2" + "${super} SHIFT, 3, movetoworkspace, 3" + "${super} SHIFT, 4, movetoworkspace, 4" + "${super} SHIFT, 5, movetoworkspace, 5" + "${super} SHIFT, 6, movetoworkspace, 6" + "${super} SHIFT, 7, movetoworkspace, 7" + "${super} SHIFT, 8, movetoworkspace, 8" + "${super} SHIFT, 9, movetoworkspace, 9" + "${super} SHIFT, 0, movetoworkspace, 10" + + # Example special workspace (scratchpad) + #"${super}, S, togglespecialworkspace, magic" + "${super} SHIFT, S, movetoworkspace, special:magic" + + # Scroll through existing workspaces with mainMod + scroll + "${super}, mouse_down, workspace, e+1" + "${super}, mouse_up, workspace, e-1" + + # Screenshot + ''${super}, Z, exec, grim -g "$(slurp)" $HOME/Pictures/Screenshots/$(date +'%s_grim.png')'' + ''${super}, U, exec, grim $HOME/Pictures/Screenshots/$(date +'%s_grim.png')'' + ]; + + bindl = [ + #", XF86AudioMute, exec, amixer set Master toggle + ", XF86AudioMute, exec, pamixer -t" + ", XF86AudioPlay, exec, playerctl play-pause" # the stupid key is called play , but it toggles + ", XF86AudioNext, exec, playerctl next" + ", XF86AudioPrev, exec, playerctl previous" + ]; + + bindle = [ + # Multi Media Control + ", XF86AudioRaiseVolume, exec, pamixer -i 5" + ", XF86AudioLowerVolume, exec, pamixer -d 5" + ", XF86MonBrightnessUp, exec, brightnessctl set +5%" + ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" + ]; + + bindm = [ + "${super}, mouse:272, movewindow" + "${super}, mouse:273, resizewindow" + ]; + }; + }; +} diff --git a/home/desktop/hyprland/hypridle.nix b/home/desktop/hyprland/hypridle.nix new file mode 100644 index 0000000..381b752 --- /dev/null +++ b/home/desktop/hyprland/hypridle.nix @@ -0,0 +1,27 @@ +{ ... }: +{ + # Hypridle configuration + services.hypridle = { + enable = true; + settings = { + general = { + after_sleep_cmd = "hyprctl dispatch dpms on"; + ignore_dbus_inhibit = false; + lock_cmd = "hyprlock"; + before_sleep_cmd = "notify-send -u critical \"I'm getting sleepy… I'll see you in my code dreams 💖\" --icon=$HOME/.config/hypr/avatar.png --app-name=Hyprlock"; + }; + + listener = [ + { + timeout = 300; + on-timeout = "hyprlock"; + } + { + timeout = 600; + on-timeout = "hyprctl dispatch dpms off"; + on-resume = "hyprctl dispatch dpms on"; + } + ]; + }; + }; +} diff --git a/home/desktop/hyprland/hyprlock.nix b/home/desktop/hyprland/hyprlock.nix new file mode 100644 index 0000000..2b31bbc --- /dev/null +++ b/home/desktop/hyprland/hyprlock.nix @@ -0,0 +1,111 @@ +{ ... }: + +{ + # Hyprlock configuration + programs.hyprlock = { + enable = true; + settings = { + + "$accent" = "$mauve"; + "$accentAlpha" = "$mauveAlpha"; + "$font" = "FiraCode Nerd Font"; + + general = { + disable_loading_bar = true; + hide_cursor = true; + }; + + background = [ + { + path = "~/Pictures/Wallpapers/lucy_with_cat.png"; + blur_passes = 1; + blur_size = 5; + } + ]; + + label = [ + # TIME + { + monitor = ""; + text = "$TIME"; + color = "$peach"; + font_size = 90; + font_family = "$font"; + position = "0, -100"; + halign = "center"; + valign = "top"; + } + + # DATE + { + monitor = ""; + text = ''cmd[update:43200000] date +"%A, %d %B %Y"''; + color = "$peach"; + font_size = 25; + font_family = "$font"; + position = "0, 100"; + halign = "center"; + valign = "bottom"; + } + + # Message + { + monitor = ""; + text = "Waiting for you..."; + color = "$peach"; + font_size = 20; + font_family = "$font"; + position = "0, 200"; + halign = "center"; + valign = "bottom"; + } + + # Weather + { + monitor = ""; + text = ''cmd[update:60000] curl -s "wttr.in/52.281311,10.527029?format=1"''; + color = "$peach"; + font_size = 20; + font_family = "$font"; + position = "0, 50"; + halign = "center"; + valign = "bottom"; + } + ]; + + # INPUT FIELD + input-field = { + monitor = ""; + size = "300, 60"; + outline_thickness = 4; + dots_size = 0.2; + dots_spacing = 0.2; + dots_center = "true"; + outer_color = "$red"; + inner_color = "$surface0"; + font_color = "$text"; + fade_on_empty = false; + placeholder_text = ''󰌾 Logged in as $USER''; + hide_input = false; + check_color = "$accent"; + fail_color = "$red"; + fail_text = "$FAIL ($ATTEMPTS)"; + capslock_color = "$yellow"; + position = "0, -150"; + halign = "center"; + valign = "center"; + }; + + image = { + monitor = ""; + path = "~/.config/hypr/avatar/avatar.png"; + size = 300; + border_color = "$teal"; + position = "0, 75"; + halign = "center"; + valign = "center"; + }; + }; + }; + +} diff --git a/home/desktop/hyprland/mako.nix b/home/desktop/hyprland/mako.nix new file mode 100644 index 0000000..e6e9aee --- /dev/null +++ b/home/desktop/hyprland/mako.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + services.mako = { + enable = true; + settings = { + font = "FiraCodeNerdFontPropo 12"; + border-size = 4; + border-radius = 8; + default-timeout = 5000; + }; + }; +} diff --git a/home/desktop/hyprland/portal.nix b/home/desktop/hyprland/portal.nix new file mode 100644 index 0000000..879a9b5 --- /dev/null +++ b/home/desktop/hyprland/portal.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: +{ + xdg.portal = { + enable = true; + xdgOpenUsePortal = true; + config = { + common.default = [ "gtk" ]; + hyprland.default = [ + "gtk" + "hyprland" + ]; + }; + extraPortals = [ + pkgs.xdg-desktop-portal-gtk + pkgs.xdg-desktop-portal-hyprland + ]; + }; +} diff --git a/home/desktop/niri/default.nix b/home/desktop/niri/default.nix new file mode 100644 index 0000000..e69de29 diff --git a/home/desktop/niri/swayidle.nix b/home/desktop/niri/swayidle.nix new file mode 100644 index 0000000..e69de29 diff --git a/home/desktop/niri/swaylock.nix b/home/desktop/niri/swaylock.nix new file mode 100644 index 0000000..e69de29 diff --git a/home/desktop/niri/swaync.nix b/home/desktop/niri/swaync.nix new file mode 100644 index 0000000..0f95483 --- /dev/null +++ b/home/desktop/niri/swaync.nix @@ -0,0 +1,110 @@ +{ ... }: +{ + services.swaync = { + enable = true; + settings = { + positionX = "center"; + positionY = "center"; + layer = "overlay"; + control-center-layer = "top"; + layer-shell = true; + cssPriority = "user"; + control-center-margin-top = 100; + control-center-margin-bottom = 200; + control-center-margin-right = 0; + control-center-margin-left = 0; + notification-2fa-action = true; + notification-inline-replies = false; + notification-icon-size = 64; + notification-body-image-height = 100; + notification-body-image-width = 200; + widgets = [ + "mpris" + "volume" + "inhibitors" + "title" + "dnd" + "notifications" + ]; + widget-config = { + + mpris = { + blacklist = [ ]; + autohide = false; + show-album-art = "always"; + loop-carousel = false; + image-size = 96; + image-radius = 12; + }; + + volume = { + label = "gain"; + show-per-app = false; + empty-list-label = "Nothin' is playin'"; + expand-button-label = "⤢"; + collaps-button-label = "⤡"; + }; + + title = { + text = "Hollerin'"; + clear-all-button = true; + button-text = "Sheriff's Pardon"; + }; + + dnd = { + text = "Let'er rest"; + }; + + menubar = { + "menu#power" = { + label = "Power"; + position = "right"; + animation-type = "slide_down"; + animation-duration = 250; + actions = [ + { + label = "Bolt It"; + command = "hyprlock"; + } + { + label = "Ride Out"; + command = "hyprctl dispatch exit"; + } + { + label = "Circle Back"; + command = "systemctl reboot"; + } + { + label = "Bet Down the Horses"; + command = "systemctl poweroff"; + } + ]; + }; + + "buttons#media" = { + position = "left"; + actions = [ + { + label = "Play/Pause"; + command = "playerctl play-pause"; + } + { + label = "Next"; + command = "playerctl next"; + } + { + label = "Previous"; + command = "playerctl previous"; + } + ]; + }; + }; + + notifications = { + vexpand = true; + }; + + }; + }; + }; +} diff --git a/home/desktop/qt.nix b/home/desktop/qt.nix new file mode 100644 index 0000000..d0e4187 --- /dev/null +++ b/home/desktop/qt.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + qt = { + enable = true; + platformTheme.name = "kvantum"; + style = { + name = "kvantum"; + package = pkgs.catppuccin-kvantum; + }; + }; + home.packages = with pkgs; [ + kdePackages.qt6ct + kdePackages.qtstyleplugin-kvantum + ]; +} diff --git a/home/desktop/rofi/background.png b/home/desktop/rofi/background.png new file mode 100644 index 0000000..fcf0626 Binary files /dev/null and b/home/desktop/rofi/background.png differ diff --git a/home/desktop/rofi/custom.rasi b/home/desktop/rofi/custom.rasi new file mode 100644 index 0000000..b9910ff --- /dev/null +++ b/home/desktop/rofi/custom.rasi @@ -0,0 +1,232 @@ +* { + rosewater: #f5e0dc; + flamingo: #f2cdcd; + pink: #f5c2e7; + mauve: #cba6f7; + red: #f38ba8; + maroon: #eba0ac; + peach: #fab387; + yellow: #f9e2af; + green: #a6e3a1; + teal: #94e2d5; + sky: #89dceb; + sapphire: #74c7ec; + blue: #89b4fa; + lavender: #b4befe; + text: #cdd6f4; + subtext1: #bac2de; + subtext0: #a6adc8; + overlay2: #9399b2; + overlay1: #7f849c; + overlay0: #6c7086; + surface2: #585b70; + surface1: #45475a; + surface0: #313244; + base: #1e1e2e; + mantle: #181825; + crust: #11111b; +} + +configuration { + show-icons: true; + modi: "window,drun,filebrowser"; + display-drun: "Apps"; + display-filebrowser: "Files"; + display-run: "RUN"; + display-window: "Active"; + drun-display-format: "{name}"; + window-format: "{w} · {c} · {t}"; +} + +/* Main Window */ +window { + /* properties for window widget */ + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 50%; + height: 90%; + x-offset: 0px; + y-offset: 0px; + + /* properties for all widgets */ + enabled: true; + border-radius: 1px; + cursor: "default"; + background-color: @base; + + border: 4px; + border-color: @yellow; +} + +/* Main Box */ + +mainbox { + enabled: true; + spacing: 0px; + background-color: transparent; + orientation: horizontal; + children: [ "imagebox", "listbox" ]; +} + +imagebox { + padding: 20px; + background-color: transparent; + background-image: url("~/.config/rofi/background.png", height); + orientation: vertical; + children: [ "inputbar", "weatherelement", "dummy", "mode-switcher" ]; +} + +listbox { + spacing: 20px; + padding: 20px; + background-color: transparent; + orientation: vertical; + children: [ "message", "listview" ]; +} + +weatherelement { + border-radius: 20px; + background-color: transparent; + text-color: @peach; + str: "Hello This is text"; +} + +dummy { + background-color: transparent; +} + +/* Input */ +inputbar { + enabled: true; + spacing: 10px; + padding: 15px; + border-radius: 10px; + background-color: @crust; + text-color: @text; + children: [ "textbox-prompt-colon", "entry" ]; +} +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + background-color: inherit; + text-color: inherit; +} +entry { + enabled: true; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: "Search"; + placeholder-color: inherit; +} + +/* Mode Switcher */ +mode-switcher{ + enabled: true; + spacing: 20px; + background-color: transparent; + text-color: @text; +} +button { + padding: 15px; + border-radius: 10px; + background-color: @base; + text-color: inherit; + cursor: pointer; +} +button selected { + background-color: @base; + text-color: @pink; +} + +/* Listview */ +listview { + enabled: true; + columns: 1; + lines: 8; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 10px; + background-color: transparent; + text-color: @text; + cursor: "default"; +} + +/* Elements */ +element { + enabled: true; + spacing: 15px; + padding: 8px; + border-radius: 10px; + background-color: transparent; + text-color: @mauve; + cursor: pointer; +} + +element normal.normal { + background-color: inherit; + text-color: inherit; +} +element normal.urgent { + background-color: inherit; + text-color: @red; +} +element normal.active { + background-color: inherit; + text-color: @blue; +} + +element selected.normal { + background-color: @crust; + text-color: @pink; +} +element selected.urgent { + background-color: @crust; + text-color: @maroon; +} +element selected.active { + background-color: @crust; + text-color: @sky; +} +element-icon { + background-color: transparent; + text-color: inherit; + size: 32px; + cursor: inherit; +} +element-text { + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +/* Message */ +message { + background-color: transparent; +} +textbox { + padding: 15px; + border-radius: 10px; + background-color: @overlay0; + text-color: @peach; + vertical-align: 0.5; + horizontal-align: 0.0; +} + +error-message { + padding: 15px; + border-radius: 20px; + background-color: @surface0; + text-color: @red; +} diff --git a/home/desktop/rofi/default.nix b/home/desktop/rofi/default.nix new file mode 100644 index 0000000..a9292b3 --- /dev/null +++ b/home/desktop/rofi/default.nix @@ -0,0 +1,31 @@ +{ + pkgs, + ... +}: +{ + + home.packages = with pkgs; [ + rofi-power-menu + rofi-calc + ]; + + programs.rofi = { + enable = true; + cycle = true; + package = pkgs.rofi-wayland; + font = "FiraCode Nerd Font Mono 12"; + + location = "center"; + terminal = "${pkgs.kitty}/bin/kitty"; + + }; + + home.file = { + ".config/rofi/background.png".source = ./background.png; + ".config/rofi/custom.rasi".source = ./custom.rasi; + ".config/rofi/power.jpg".source = ./power.jpg; + ".config/rofi/power.rasi".source = ./power.rasi; + ".config/rofi/smoking_girl.png".source = ./smoking_girl.png; + }; + +} diff --git a/home/desktop/rofi/power.jpg b/home/desktop/rofi/power.jpg new file mode 100644 index 0000000..57fcb46 Binary files /dev/null and b/home/desktop/rofi/power.jpg differ diff --git a/home/desktop/rofi/power.rasi b/home/desktop/rofi/power.rasi new file mode 100644 index 0000000..0b62cd4 --- /dev/null +++ b/home/desktop/rofi/power.rasi @@ -0,0 +1,163 @@ +* { + rosewater: #f5e0dc; + flamingo: #f2cdcd; + pink: #f5c2e7; + mauve: #cba6f7; + red: #f38ba8; + maroon: #eba0ac; + peach: #fab387; + yellow: #f9e2af; + green: #a6e3a1; + teal: #94e2d5; + sky: #89dceb; + sapphire: #74c7ec; + blue: #89b4fa; + lavender: #b4befe; + text: #cdd6f4; + subtext1: #bac2de; + subtext0: #a6adc8; + overlay2: #9399b2; + overlay1: #7f849c; + overlay0: #6c7086; + surface2: #585b70; + surface1: #45475a; + surface0: #313244; + base: #1e1e2e; + mantle: #181825; + crust: #11111b; +} + +configuration { + font: "Fira Code Bold 20px"; + show-icons: true; +} + +/* +USE_BUTTONS=YES +*/ + +/*****----- Main Window -----*****/ +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 1000px; + x-offset: 0px; + y-offset: 0px; + + padding: 0px; + border: 4px solid; + border-radius: 2px; + border-color: @blue; + cursor: "default"; + background-color: @base; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 0px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @blue; + background-color: transparent; + children: [ "inputbar", "listview", "message" ]; +} + + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 20px; + padding: 100px 40px; + background-color: transparent; + background-image: url("~/.config/rofi/power.jpg", width); + children: [ "textbox-prompt-colon", "prompt"]; +} + +dummy { + background-color: transparent; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: " System"; + padding: 15px; + border: 0px 0px 0px 10px; + border-radius: 100% 100% 0px 100%; + border-color: @blue; + background-color: @crust; + text-color: @text; +} +prompt { + enabled: true; + padding: 15px; + border: 0px; + border-radius: 0px 100% 100% 100%; + border-color: @blue; + background-color: @crust; + text-color: @text; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 6; + lines: 1; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 30px; + margin: 10px; + background-color: transparent; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + padding: 10px; + border-radius: 1%; + background-color: @crust; + text-color: @text; + cursor: pointer; + children: [ element-text ]; +} +element-text { + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} +element selected.normal { + background-color: @crust; + text-color: @yellow; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 15px; + border-radius: 0px; + background-color: @crust; + text-color: @yellow; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + + diff --git a/home/desktop/rofi/smoking_girl.png b/home/desktop/rofi/smoking_girl.png new file mode 100644 index 0000000..8e32766 Binary files /dev/null and b/home/desktop/rofi/smoking_girl.png differ diff --git a/home/desktop/waybar/common.nix b/home/desktop/waybar/common.nix new file mode 100644 index 0000000..672224c --- /dev/null +++ b/home/desktop/waybar/common.nix @@ -0,0 +1,181 @@ +{ + widgets = { + "group/media" = { + orientation = "horizontal"; + + modules = [ + "mpris" + "custom/cava" + "wireplumber" + ]; + }; + + mpris = { + format = "{player_icon}"; + format-paused = "{status_icon}"; + max-length = 100; + player-icons = { + default = "||"; + mpv = "||"; + }; + status-icons = { + paused = "▶"; + }; + }; + + "custom/cava" = { + exec = "sh ~/.config/waybar/cava.sh"; + format = "{} ♪"; + on-click = "hyprctl dispatch focuswindow class:spotify"; + }; + + wireplumber = { + format = "{volume}%"; + format-muted = ""; + max-volume = 110; + scroll-step = 0.2; + }; + + "group/hardware" = { + orientation = "horizontal"; + modules = [ + "cpu" + "network" + "memory" + "disk" + "temperature" + ]; + }; + + network = { + # Wifi + tooltip = true; + format-wifi = "{icon} "; + format-icons = [ + "󰤟" + "󰤢" + "󰤥" + ]; + rotate = 0; + + # Ethernet + format-ethernet = "⇵{bandwidthTotalBits}"; + tooltip-format = "Network: {essid}\nSignal strength: {signaldBm}dBm ({signalStrength}%)\nFrequency: {frequency}MHz\nInterface: {ifname}\nIP: {ipaddr}/{cidr}\nGateway: {gwaddr}\nNetmask: {netmask}\nCurrent󰈀 : {bandwidthTotalBits}\nUp 󰶣: {bandwidthUpBits}\nDown 󰶡: {bandwidthDownBits}"; + format-linked = "󰈀 {ifname} (No IP)"; + format-disconnected = " "; + tooltip-format-disconnected = "Disconnected"; + interval = 2; + }; + + memory = { + interval = 1; + #rotate = 270; + format = "{icon} {percentage}%"; + format-icons = [ + "󰝦" + "󰪞" + "󰪟" + "󰪠" + "󰪡" + "󰪢" + "󰪣" + "󰪤" + "󰪥" + ]; + max-length = 10; + }; + + cpu = { + interval = 1; + format = "{icon} {usage}%"; + #rotate = 270; + format-icons = [ + "󰝦" + "󰪞" + "󰪟" + "󰪠" + "󰪡" + "󰪢" + "󰪣" + "󰪤" + "󰪥" + ]; + }; + + temperature = { + format = " {temperatureC}°C"; + thermal-zone = 0; + hwmon-path = "/sys/class/thermal/thermal_zone1/temp"; + critical-threshold = 80; + }; + + disk = { + format = " {percentage_free}%"; + tooltip = true; + tooltip-format = "{free} / {total} ({percentage_free})"; + }; + + clock = { + format = "{:%a %b %d, %I:%M %p}"; + rotate = 0; + on-click = " "; + tooltip-format = "{calendar}"; + calendar = { + mode = "month"; + mode-mon-col = 3; + on-scroll = 1; + on-click-right = "mode"; + format = { + months = "{}"; + weekdays = "{}"; + today = "{}"; + }; + }; + actions = { + on-click-right = "mode"; + on-click-forward = "tz_up"; + on-click-backward = "tz_down"; + on-scroll-up = "shift_up"; + on-scroll-down = "shift_down"; + }; + }; + + "custom/nixicon" = { + format = " "; + on-click = "rofi -show drun -theme $HOME/.config/rofi/custom.rasi"; + tooltip = false; + }; + + "custom/weather" = { + format = "{}"; + return-type = "json"; + exec = '' + curl -s -X GET "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$OPENWEATHER_API_KEY&units=metric&lang=en" | jq -c '{text: "\(.name) \(.main.temp)C°"}' + ''; + interval = 120; + on-click = '' + data=$(curl -s -X GET "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$OPENWEATHER_API_KEY&units=metric&lang=en") + city=$(echo "$data" | jq -r '.name') + temp=$(echo "$data" | jq -r '.main.temp') + feels=$(echo "$data" | jq -r '.main.feels_like') + humidity=$(echo "$data" | jq -r '.main.humidity') + wind=$(echo "$data" | jq -r '.wind.speed') + clouds=$(echo "$data" | jq -r '.clouds.all') + sunrise=$(echo "$data" | jq -r '.sys.sunrise | strftime("%H:%M")') + sunset=$(echo "$data" | jq -r '.sys.sunset | strftime("%H:%M")') + notify-send "$city" "Temperature: $temp °C\nFeels Like: $feels °C\nHumidity: $humidity%\nWind: $wind m/s\nClouds: $clouds%\nSunrise at: $sunrise\nSunset at: $sunset" -u normal --icon="$HOME/Pictures/Avatar/avatar_weather_no_bg.png" + ''; + }; + + "custom/wallpaper" = { + format = "【{} 】"; + exec = "basename $(swww query | grep -oP 'image: \\K.*')"; + interval = 5; + on-click = "waypaper"; + tooltip = true; + tooltip-format = "{}"; + max-length = 30; + }; + }; + +} diff --git a/home/desktop/waybar/configs/cava.sh b/home/desktop/waybar/configs/cava.sh new file mode 100644 index 0000000..a12dac4 --- /dev/null +++ b/home/desktop/waybar/configs/cava.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Not my own work. Credit to original author + +#----- Optimized bars animation without much CPU usage increase -------- +bar="▁▂▃▄▅▆▇█" +dict="s/;//g" + +# Calculate the length of the bar outside the loop +bar_length=${#bar} + +# Create dictionary to replace char with bar +for ((i = 0; i < bar_length; i++)); do + dict+=";s/$i/${bar:$i:1}/g" +done + +# Create cava config +config_file="/tmp/bar_cava_config" +cat >"$config_file" < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/home/desktop/waybar/configs/style.css b/home/desktop/waybar/configs/style.css new file mode 100644 index 0000000..dc25e86 --- /dev/null +++ b/home/desktop/waybar/configs/style.css @@ -0,0 +1 @@ +*{border:none;min-height:10px;font-family:FiraCode Nerd Font;font-size:15px}window#waybar{background:@crust}window#waybar.hidden{opacity:.2}󠀰 #media,#clock,#cpu,#memory,#disk,#temperature,#network,#custom-wallpaper,#media,#custom-weather{color:@crust;margin-top:6px;margin-bottom:6px;padding-left:10px;padding-right:10px;transition:none}#custom-nixicon,#cpu{border-top-left-radius:10px;border-bottom-left-radius:10px;margin-left:5px}#clock,#temperature{border-top-right-radius:10px;border-bottom-right-radius:10px;margin-right:20px}#custom-nixicon{background-image:url(nix-snowflake.svg);background-position:50%;background-repeat:no-repeat;background-size:contain;min-width:24px;min-height:24px;margin-top:6px;margin-bottom:6px;margin-left:15px;padding:0 15px 0 10px}#clock{background:@yellow}#cpu{background:@blue}#memory{background:@red}#disk{background:@peach}#temperature{background:@sky}#network{background:@lavender;padding-right:13px}#workspaces{border-radius:10px;margin:6px 5px;padding:0 6px}#workspaces button{color:@text;background:0 0;border:none;padding:4px;transition:color .3s,text-shadow .3s,transform .3s}#workspaces button.occupied{color:@red}#workspaces button.active{color:@green;text-shadow:0 0 4px @green}#workspaces button:hover{color:@teal;border:none}#media{background:@overlay2;color:@crust;border-radius:10px;margin-left:20px}#custom-cava{color:@green}#wireplumber,#custom-cava,#mpris{margin-left:10px;margin-right:5px}#wireplumber{margin-right:5px}#custom-weather{background:@sky;color:@crust;border-radius:10px;margin-right:20px}#custom-notification{background:@green;border-radius:10px;padding-left:10px;padding-right:5px;font-family:NotoSansMono Nerd Font}#custom-wallpaper{background:@red;color:@mantle;border-radius:10px;margin-left:5px} diff --git a/home/desktop/waybar/configs/style.src.css b/home/desktop/waybar/configs/style.src.css new file mode 100644 index 0000000..d6ff9f0 --- /dev/null +++ b/home/desktop/waybar/configs/style.src.css @@ -0,0 +1,173 @@ +* { + border: none; + font-family: "FiraCode Nerd Font"; + font-size: 15px; + min-height: 10px; +} + +window#waybar { + background: @crust; +} + +window#waybar.hidden { + opacity: 0.2; +} +󠀰 +/* - Genera rules for visible modules -- */ +#media, +#clock, +#cpu, +#memory, +#disk, +#temperature, +#network, +#custom-wallpaper, +#media, +#custom-weather { + color: @crust; + margin-top: 6px; + margin-bottom: 6px; + padding-left: 10px; + padding-right: 10px; + transition: none; +} + +/* Separation to the left */ +#custom-nixicon, +#cpu { + margin-left: 5px; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; +} + +/* Separation to the rigth */ +#clock, +#temperature { + margin-right: 20px; + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; +} + +/* -- Specific styles -- */ + +#custom-nixicon { + background-image: url("nix-snowflake.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 24px; + min-width: 24px; + + padding: 0px; + padding-right: 15px; + padding-left: 10px; + margin-top: 6px; + margin-bottom: 6px; + margin-left: 15px; +} + +/* Hardware Group */ +#clock { + background: @yellow; +} + +#cpu { + background: @blue; +} + +#memory { + background: @red; +} + +#disk { + background: @peach; +} + +#temperature { + background: @sky; +} + +#network { + background: @lavender; + padding-right: 13px; +} + +/* Workspace */ +#workspaces { + border-radius: 10px; + margin: 6px 5px; + padding: 0px 6px; +} + +#workspaces button { + color: @text; + background: transparent; + padding: 4px 4px; + transition: color 0.3s ease, text-shadow 0.3s ease, transform 0.3s ease; + border: none; +} + +#workspaces button.occupied { + color: @red; +} + +#workspaces button.active { + color: @green; + text-shadow: 0 0 4px @green; +} + +#workspaces button:hover { + color: @teal; + border: none; +} + +#workspaces button.active:hover {} + + + +/* Media Group */ +#media { + background: @overlay2; + border-radius: 10px; + color: @crust; + margin-left: 20px; +} + +#custom-cava { + color: @green; +} + +#wireplumber, #custom-cava, #mpris { + margin-left: 10px; + margin-right: 5px; +} + +#wireplumber { + margin-right: 5px; +} + + +/* Weather */ +#custom-weather { + background: @sky; + color: @crust; + border-radius: 10px; + margin-right: 20px; +} + +/* SwayNC */ +#custom-notification { + font-family: "NotoSansMono Nerd Font"; + background: @green; + border-radius: 10px; + padding-left: 10px; + padding-right: 5px; +} + +/* Wallpaper */ +#custom-wallpaper { + background: @red; + color: @mantle; + border-radius: 10px; + margin-left: 5px; +} diff --git a/home/desktop/waybar/default.nix b/home/desktop/waybar/default.nix new file mode 100644 index 0000000..58822c3 --- /dev/null +++ b/home/desktop/waybar/default.nix @@ -0,0 +1,16 @@ +{ + pkgs, + compositor ? "hyprland", + ... +}: +{ + programs.waybar = { + enable = true; + package = pkgs.waybar; + } + // (import ./dual.nix { inherit compositor; }); + home.file.".config/waybar" = { + source = ./configs; + recursive = true; + }; +} diff --git a/home/desktop/waybar/dual.nix b/home/desktop/waybar/dual.nix new file mode 100644 index 0000000..ce67f16 --- /dev/null +++ b/home/desktop/waybar/dual.nix @@ -0,0 +1,52 @@ +{ + compositor ? "hyprland", +}: +let + common = import ./common.nix; + wm = if compositor == "hyprland" then import ./hyprland.wm.nix else import ./niri-wm.nix; +in +{ + enable = true; + settings = { + mainBar = { + layer = "top"; + position = "top"; + height = 30; + output = [ "DP-1" ]; + modules-left = [ + "custom/nixicon" + "clock" + ]; + modules-center = [ + "hyprland/workspaces" + "niri/workspaces" + "custom/mako" + "custom/swaync" + ]; + modules-right = [ + "group/hardware" + ]; + } + // common.widgets + // wm.widgets; + + secondBar = { + layer = "top"; + position = "top"; + height = 30; + output = [ "HDMI-A-2" ]; + modules-left = [ + "group/media" + "custom/wallpaper" + ]; + modules-center = [ + "hyprland/workspaces" + "niri/workspaces" + ]; + modules-right = [ "custom/weather" ]; + } + // common.widgets + // wm.widgets; + }; + +} diff --git a/home/desktop/waybar/hyprland-wm.nix b/home/desktop/waybar/hyprland-wm.nix new file mode 100644 index 0000000..f20a019 --- /dev/null +++ b/home/desktop/waybar/hyprland-wm.nix @@ -0,0 +1,23 @@ +{ + widgets = { + "hyprland/workspaces" = { + format = "{icon}"; + format-icons = { + default = ""; + active = ""; + }; + }; + "custom/mako" = { + tooltip = false; + format = "{icon}"; + format-icons = { + enabled = " "; + disabled = " "; + }; + return-type = "json"; + exec = "makoctl mode | grep -q do-not-disturb && echo '{\"text\":\"\",\"class\":\"disabled\"}' || echo '{\"text\":\"\",\"class\":\"enabled\"}'"; + on-click = "makoctl mode -t do-not-disturb"; + interval = 1; + }; + }; +} diff --git a/home/desktop/waybar/niri-wm.nix b/home/desktop/waybar/niri-wm.nix new file mode 100644 index 0000000..ac653aa --- /dev/null +++ b/home/desktop/waybar/niri-wm.nix @@ -0,0 +1,31 @@ +{ + widgets = { + "niri/workspaces" = { + format = "{icon}"; + format-icons = { + default = ""; + active = ""; + }; + }; + "custom/swaync" = { + tooltip = false; + format = "{icon}"; + format-icons = { + notification = ""; + none = " "; + dnd-notification = ""; + dnd-none = " "; + inhibited-notification = ""; + inhibited-none = " "; + dnd-inhibited-notification = ""; + dnd-inhibited-none = " "; + }; + return-type = "json"; + exec-if = "which swaync-client"; + exec = "swaync-client -swb"; + on-click = "swaync-client -t -sw"; + on-click-right = "swaync-client -d -sw"; + escape = true; + }; + }; +} diff --git a/home/desktop/waypaper.ini b/home/desktop/waypaper.ini new file mode 100644 index 0000000..4388f07 --- /dev/null +++ b/home/desktop/waypaper.ini @@ -0,0 +1,25 @@ +[Settings] +# Which backend to use +backend = swww + +# Wallpaper directory to browse +wallpaper_dirs = ~/Pictures/Wallpapers/ + +# Transition settings for swww +swww_transition = wave +swww_fps = 30 +swww_duration = 0.7 + +# Restore wallpaper on startup +restore_last = true + +# Fit options: fill | contain | cover | center | tile +mode = fill + +# Enable preview thumbnails +show_thumbnails = true + +# Random wallpaper button +random = true + + diff --git a/home/fastfetch.jsonc b/home/fastfetch.jsonc new file mode 100644 index 0000000..052e1d9 --- /dev/null +++ b/home/fastfetch.jsonc @@ -0,0 +1,171 @@ +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "type": "kitty-icat", + "source": "~/Pictures/Avatar/avatar_no_bg.png", + // "height": 15, + "width": 36, + "padding": { + "top": 0, + "left": 0 + } + }, + "modules": [ + "break", + { + "type": "custom", + "format": "\u001b[90m┌──────────────────────Hardware──────────────────────┐" + }, + { + "type": "host", + "key": " PC", + "keyColor": "green" + }, + { + "type": "cpu", + "key": "│ ├", + "keyColor": "green" + }, + { + "type": "gpu", + "key": "│ ├󰍛", + "keyColor": "green" + }, + { + "type": "disk", + "key": "│ ├", + "keyColor": "green" + }, + { + "type": "memory", + "key": "└ └󰍛", + "keyColor": "green" + }, + { + "type": "custom", + "format": "\u001b[90m└────────────────────────────────────────────────────┘" + }, + "break", + { + "type": "custom", + "format": "\u001b[90m┌──────────────────────Software──────────────────────┐" + }, + { + "type": "os", + "key": " OS", + "keyColor": "yellow" + }, + { + "type": "kernel", + "key": "│ ├", + "keyColor": "yellow" + }, + { + "type": "bios", + "key": "│ ├", + "keyColor": "yellow" + }, + { + "type": "packages", + "key": "│ ├󰏖", + "keyColor": "yellow" + }, + { + "type": "shell", + "key": "└ └", + "keyColor": "yellow" + }, + "break", + { + "type": "de", + "key": " DE", + "keyColor": "blue" + }, + { + "type": "lm", + "key": "│ ├", + "keyColor": "blue" + }, + { + "type": "wm", + "key": "│ ├", + "keyColor": "blue" + }, + { + "type": "wmtheme", + "key": "│ ├󰉼", + "keyColor": "blue" + }, + { + "type": "terminal", + "key": "└ └", + "keyColor": "blue" + }, + { + "type": "custom", + "format": "\u001b[90m└────────────────────────────────────────────────────┘" + }, + "break", + { + "type": "custom", + "format": "\u001b[90m┌─────────────────Uptime / Age / DT──────────────────┐" + }, + { + "type": "command", + "key": " OS Age ", + "keyColor": "magenta", + "text": "birth_install=$(stat -c %W /); current=$(date +%s); time_progression=$((current - birth_install)); days_difference=$((time_progression / 86400)); echo $days_difference days" + }, + { + "type": "uptime", + "key": " Uptime ", + "keyColor": "magenta" + }, + { + "type": "datetime", + "key": " DateTime ", + "keyColor": "magenta" + }, + { + "type": "custom", + "format": "\u001b[90m└────────────────────────────────────────────────────┘" + }, + "break", + { + "type": "custom", + "format": "\u001b[90m┌─────────────────────Networking─────────────────────┐" + }, + { + "type": "publicip", + "key": " Public ", + "keyColor": "magenta" + }, + { + "type": "localip", + "key": " Local ", + "keyColor": "magenta" + }, + { + "type": "dns", + "key": " DNS ", + "keyColor": "magenta" + }, + { + "type": "netio", + "key": " Net I/O ", + "keyColor": "magenta" + }, + { + "type": "custom", + "format": "\u001b[90m└────────────────────────────────────────────────────┘" + }, + { + "type": "colors", + "paddingLeft": 2, + "symbol": "circle" + }, + "break", + ] +} + + diff --git a/home/floorp.nix b/home/floorp.nix new file mode 100644 index 0000000..ecf73fb --- /dev/null +++ b/home/floorp.nix @@ -0,0 +1,5 @@ +_: { + programs.floorp = { + enable = true; + }; +} diff --git a/home/git.nix b/home/git.nix new file mode 100644 index 0000000..c552777 --- /dev/null +++ b/home/git.nix @@ -0,0 +1,27 @@ +{ primaryUser, pkgs, ... }: +{ + + home.packages = with pkgs; [ + gh + gnupg + ]; + + programs.git = { + enable = true; + userName = "DerGrumpf"; # TODO replace + userEmail = "p.keier@beyerstedt-it.de"; # TODO replace + + lfs.enable = true; + + ignores = [ "**/.DS_STORE" ]; + + extraConfig = { + github = { + user = primaryUser; + }; + init = { + defaultBranch = "main"; + }; + }; + }; +} diff --git a/home/neovim/alpha.nix b/home/neovim/alpha.nix new file mode 100644 index 0000000..52357f4 --- /dev/null +++ b/home/neovim/alpha.nix @@ -0,0 +1,147 @@ +{ pkgs, ... }: { + # Alpha: Start screen/dashboard for Neovim + # Shows a custom ASCII art header and quick action buttons on startup. + programs.nixvim.plugins.alpha = { + enable = true; + settings.layout = [ + { + type = "padding"; + val = 2; + } + { + type = "text"; + val = [ + "⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣯⣿⠿⣟⣷⣯⣛⢿⣿⣿⣾⣟⣿⣿⣿⣿⣿⣿⣿⣿⣿" + "⣿⣿⣿⣿⣿⣿⣿⡿⣵⣿⡿⣴⣽⡟⣳⢿⢽⣽⣕⣽⢿⡿⣿⣟⣿⣿⣿⣿⣿⣿⣿" + "⣿⣿⣿⣷⣿⣿⢟⣫⣿⢟⢟⣾⣾⣿⣿⣞⢳⣻⢞⣎⠿⢞⣊⣿⣞⣿⣿⣿⣿⣿⢽" + "⣿⣿⣿⣿⣿⣏⢯⣿⣏⣏⠔⢇⣿⢢⢆⢀⢆⣧⣼⢻⢰⡧⢻⣝⣏⡸⣧⣾⣿⣿⣿" + "⣿⣿⣿⣿⡟⣻⣿⣿⡾⡿⡼⢸⡝⣝⡳⢢⣧⢳⣳⢷⡇⣗⢺⡺⣿⡧⣿⣿⣿⢿⢿" + "⣿⡿⣿⣼⡼⣿⣿⡗⡧⣧⠁⡝⣧⣳⠅⡾⠈⣎⢮⣧⣿⣿⣗⣷⣻⢷⣏⣼⢏⣺⣿" + "⣿⣿⣿⣻⣿⣿⣿⢧⣿⢹⠉⢷⢿⣧⣲⡏⡀⡈⢆⠳⣿⡿⢿⣿⣱⢿⢫⣷⣝⣿⣿" + "⣿⣿⣿⡯⡟⣿⣿⢽⣡⠟⢿⣮⠁⠙⠛⠈⡴⢿⣿⡷⣬⣽⢽⠧⣷⡏⣿⡇⣧⣽⣿" + "⣿⠟⢻⡧⡇⣿⡇⣇⣆⢄⡜⢃⡀⡀⡀⡀⡀⢎⣁⠁⣸⣗⣸⣿⣧⣼⡿⢹⢿⢾⣿" + "⣿⣷⣾⣿⢻⣿⢧⢻⣽⡀⡀⡀⡀⢄⡀⡀⡀⡀⡀⢀⣷⡸⡟⣿⣶⣻⣧⡛⡱⢝⣿" + "⣿⣿⣿⣿⢸⡿⢚⡜⣿⣇⡀⡀⡀⡀⡀⡀⡀⡀⠚⢁⢣⣜⡿⣿⡇⢼⣿⠨⣸⣿⣿" + "⣿⣄⣿⣗⢾⢻⣧⢿⣾⣿⣦⡀⡀⠑⠚⠉⡀⡀⣤⣿⢨⣿⠗⣻⢣⣿⢹⢈⣽⣿⣿" + "⣿⣿⣿⣿⢎⡄⢿⣞⡇⣿⠹⣿⣶⣀⡀⣀⡴⡩⢸⢏⣿⣿⣶⢻⣾⢏⡞⠡⢽⣇⣾" + "⣿⣿⣿⣮⣼⢬⣦⢿⣳⣌⠧⡉⠈⣇⣛⣁⣈⣼⣿⡸⠫⠛⠐⠛⠕⣙⣻⣬⣼⣿⣿" + "⢟⢿⣿⣿⣿⡢⣃⣪⣭⣡⣤⣶⠟⡿⠿⠿⠿⠛⢁⣿⣿⢩⠉⡀⠈⠓⡝⣿⣿⣿⣿" + "⣾⣿⣿⣿⣿⠞⢔⡣⡴⣾⣿⠓⣤⢧⡼⣉⠠⢤⣿⣿⠇⠃⡀⡀⡀⡀⡸⢿⣾⣿⣿" + "⣿⣿⣿⡿⣺⡸⢗⢠⣇⣿⣿⠊⠃⡀⠉⡀⢠⣿⣿⠟⡸⡀⡀⡀⡀⡀⣃⣬⠽⠿⣿" + "⣿⣿⣿⣿⡇⡏⢸⣿⠟⣽⡇⡀⡀⡀⡀⣴⣟⢭⣾⣿⡇⠎⣠⠒⠉⠈⢀⡀⢨⡋⣿" + "⠛⠛⠛⠋⠃⠓⠚⠛⠘⠛⠃⡀⠊⡀⠛⠛⠛⠂⠛⠛⠓⠁⠚⡀⠂⠒⠒⠐⠒⠋⠛" + ]; + opts = { + position = "center"; + hl = "Type"; + }; + } + { + type = "padding"; + val = 2; + } + { + type = "group"; + val = [ + { + type = "button"; + val = "[+] New file"; + on_press.__raw = + "function() vim.cmd[[ene]] vim.cmd[[startinsert]] end"; + opts = { + keymap = [ "n" "e" ":ene startinsert " { } ]; + shortcut = "e"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + { + type = "button"; + val = "[?] Find file"; + on_press.__raw = "function() vim.cmd[[Telescope find_files]] end"; + opts = { + keymap = [ "n" "f" ":Telescope find_files " { } ]; + shortcut = "f"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + { + type = "button"; + val = "[~] Recent files"; + on_press.__raw = "function() vim.cmd[[Telescope oldfiles]] end"; + opts = { + keymap = [ "n" "r" ":Telescope oldfiles " { } ]; + shortcut = "r"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + { + type = "button"; + val = "[Y] Yazi"; + on_press.__raw = "function() require('yazi').yazi() end"; + opts = { + keymap = [ "n" "y" ":Yazi" { } ]; + shortcut = "y"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + { + type = "button"; + val = "[A] Open Prompt"; + #on_press.__raw = "function() require('yazi').yazi() end"; + opts = { + keymap = [ "n" "a" ":AvanteChatNew" { } ]; + shortcut = "a"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + { + type = "button"; + val = "[X] Quit"; + on_press.__raw = "function() vim.cmd[[qa]] end"; + opts = { + keymap = [ "n" "q" ":qa" { } ]; + shortcut = "q"; + position = "center"; + cursor = 3; + width = 50; + align_shortcut = "right"; + hl_shortcut = "Keyword"; + }; + } + ]; + } + { + type = "padding"; + val = 2; + } + { + type = "text"; + val = "Circuits hum in anticipation of your will."; + opts = { + position = "center"; + hl = "Comment"; + }; + } + ]; + }; +} diff --git a/home/neovim/avante.nix b/home/neovim/avante.nix new file mode 100644 index 0000000..edbbf9e --- /dev/null +++ b/home/neovim/avante.nix @@ -0,0 +1,106 @@ +{ pkgs, ... }: { + # Avante: AI-powered coding assistant (Cursor-like experience in Neovim) + programs.nixvim = { + + plugins = { + markdown-preview.enable = true; + render-markdown.enable = true; + #extraConfigLuaPre = '' + # vim.env.GROQ_API_KEY = os.getenv("GROQ_API_KEY") + #''; + # TODO: Integrate CoPilot https://github.com/settings/copilot/features + avante = { + enable = true; + autoLoad = true; + settings = { + provider = "groq"; + + providers.groq = { + __inherited_from = "openai"; + api_key_name = "GROQ_API_KEY"; + endpoint = "https://api.groq.com/openai/v1/"; + model = "groq/compound-mini"; + disable_tools = true; + extra_request_body = { + temperature = 1; + max_tokens = 8192; + tools = null; + tool_choice = "none"; + }; + }; + + # auto_suggestions_provider = "copilot"; + + render = { markdown = true; }; + + behaviour = { + auto_suggestions = false; + auto_set_highlight_group = true; + auto_set_keymaps = true; + auto_apply_diff_after_generation = false; + support_paste_from_clipboard = false; + }; + + mappings = { + ask = "aa"; + edit = "ae"; + refresh = "ar"; + diff = { + ours = "co"; + theirs = "ct"; + all_theirs = "ca"; + both = "cb"; + cursor = "cc"; + next = "]x"; + prev = "[x"; + }; + suggestion = { + accept = ""; + next = ""; + prev = ""; + dismiss = ""; + }; + jump = { + next = "]]"; + prev = "[["; + }; + submit = { + normal = ""; + insert = ""; + }; + sidebar = { + switch_windows = ""; + reverse_switch_windows = ""; + }; + }; + + hints = { enabled = true; }; + + windows = { + position = "right"; + wrap = true; + width = 30; + sidebar_header = { + align = "center"; + rounded = true; + }; + }; + + highlights = { + diff = { + current = "DiffText"; + incoming = "DiffAdd"; + }; + }; + + diff = { + autojump = true; + list_opener = "copen"; + }; + }; + }; + + extraPackages = with pkgs; [ curl ]; + }; + }; +} diff --git a/home/neovim/catppuccin.nix b/home/neovim/catppuccin.nix new file mode 100644 index 0000000..98ba46c --- /dev/null +++ b/home/neovim/catppuccin.nix @@ -0,0 +1,34 @@ +{ pkgs, ... }: +{ + # Catppuccin: Soothing pastel theme for Neovim + # Provides consistent theming across plugins with transparency support. + programs.nixvim = { + colorschemes.catppuccin = { + enable = true; + settings = { + flavour = "mocha"; + transparent_background = true; + term_colors = true; + integrations = { + treesitter = true; + cmp = true; + gitsigns = true; + telescope = { + enabled = true; + }; + notify = true; + mini = { + enabled = true; + }; + }; + }; + }; + + # Custom highlight overrides + extraConfigLua = '' + local colors = require("catppuccin.palettes").get_palette("mocha") + vim.api.nvim_set_hl(0, "LineNr", { fg = colors.text, bg = "NONE" }) + vim.api.nvim_set_hl(0, "CursorLineNr", { fg = colors.pink, bg = "NONE", bold = true }) + ''; + }; +} diff --git a/home/neovim/conform.nix b/home/neovim/conform.nix new file mode 100644 index 0000000..54186a5 --- /dev/null +++ b/home/neovim/conform.nix @@ -0,0 +1,33 @@ +{ pkgs, ... }: { + # Conform: Code formatter that runs external formatting tools + # Automatically formats code on save for consistent style. + programs.nixvim = { + plugins.conform-nvim = { + enable = true; + + settings = { + formatters_by_ft = { + lua = [ "stylua" ]; + nix = [ "nixfmt" ]; + python = [ "black" ]; + rust = [ "rustfmt" ]; + rasi = [ "prettierd" ]; + }; + + format_on_save = { + timeout_ms = 2000; + lsp_fallback = true; + }; + }; + }; + + # Install formatters + extraPackages = with pkgs; [ + stylua + nixfmt-classic + black + rustfmt + prettierd + ]; + }; +} diff --git a/home/neovim/default.nix b/home/neovim/default.nix new file mode 100644 index 0000000..758eeee --- /dev/null +++ b/home/neovim/default.nix @@ -0,0 +1,102 @@ +{ pkgs, ... }: +{ + imports = [ + ./treesitter.nix + ./lint.nix + ./lsp.nix + ./conform.nix + ./lualine.nix + ./yazi.nix + ./toggleterm.nix + ./telescope.nix + ./catppuccin.nix + ./alpha.nix + ./avante.nix + ./openscad.nix + ./molten.nix + ./live-server.nix + ./which-key.nix + ]; + + home.packages = with pkgs; [ + nil + biome + nixfmt-rfc-style + ]; + + programs.nixvim = { + enable = true; + defaultEditor = true; + + # Leader key + globals.mapleader = " "; + + plugins.web-devicons.enable = true; + + opts = { + number = true; # Show line numbers + cursorline = true; # Highlight current line + showmode = true; # already in statusline + hlsearch = true; # Highlight search result + incsearch = true; # Incremental Search + tabstop = 4; + termguicolors = true; # Enable 24-bit colormode + }; + + # Clipboard keymaps - yank to system clipboard + keymaps = [ + # Yank operations + { + mode = "n"; + key = "y"; + action = ''"+y''; + options.desc = "Yank to clipboard"; + } + { + mode = "v"; + key = "y"; + action = ''"+y''; + options.desc = "Yank to clipboard"; + } + { + mode = "n"; + key = "Y"; + action = ''"+Y''; + options.desc = "Yank line to clipboard"; + } + # Delete operations + { + mode = "n"; + key = "d"; + action = ''"+d''; + options.desc = "Delete to clipboard"; + } + { + mode = "v"; + key = "d"; + action = ''"+d''; + options.desc = "Delete to clipboard"; + } + { + mode = "n"; + key = "D"; + action = ''"+D''; + options.desc = "Delete line to clipboard"; + } + # Paste operations + { + mode = "n"; + key = "p"; + action = ''"+p''; + options.desc = "Paste from clipboard"; + } + { + mode = "v"; + key = "p"; + action = ''"+p''; + options.desc = "Paste from clipboard"; + } + ]; + }; + +} diff --git a/home/neovim/lint.nix b/home/neovim/lint.nix new file mode 100644 index 0000000..ac178c6 --- /dev/null +++ b/home/neovim/lint.nix @@ -0,0 +1,42 @@ +{ pkgs, ... }: +{ + # nvim-lint: Asynchronous linter that runs external linting tools + # to find errors and style issues without blocking the editor. + # Runs automatically after saving files. + programs.nixvim = { + plugins.lint = { + enable = true; + + # Configure linters for each filetype + lintersByFt = { + lua = [ "luacheck" ]; + nix = [ "statix" ]; # Nix static analyzer + python = [ "ruff" ]; + javascript = [ "eslint" ]; + rust = [ "clippy" ]; + # rasi has no common linter + }; + + # Trigger linting after saving a file + autoCmd = { + event = [ "BufWritePost" ]; + callback = { + __raw = '' + function() + require('lint').try_lint() + end + ''; + }; + }; + }; + + # Install linter binaries + extraPackages = with pkgs; [ + lua54Packages.luacheck + statix + ruff + nodePackages.eslint + clippy + ]; + }; +} diff --git a/home/neovim/live-server.nix b/home/neovim/live-server.nix new file mode 100644 index 0000000..20a13f1 --- /dev/null +++ b/home/neovim/live-server.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: { + # Live Server: Auto-reload browser for web development + # Uses browser-sync for live reload functionality + programs.nixvim = { + keymaps = [{ + mode = "n"; + key = "ls"; + action = + "terminal browser-sync start --server --files '*.html, *.css, *.js' --no-notify"; + options.desc = "Start live server (browser-sync)"; + }]; + + extraPackages = with pkgs; [ nodePackages.browser-sync ]; + }; +} diff --git a/home/neovim/lsp.nix b/home/neovim/lsp.nix new file mode 100644 index 0000000..3fe2059 --- /dev/null +++ b/home/neovim/lsp.nix @@ -0,0 +1,91 @@ +{ pkgs, ... }: +{ + # LSP configuration: Language Server Protocol provides IDE features + # like autocomplete, go-to-definition, diagnostics, and more. + programs.nixvim = { + plugins = { + # LSP configuration + lsp = { + enable = true; + + # Language servers for each language + servers = { + lua_ls = { + enable = true; + settings = { + Lua = { + runtime.version = "LuaJIT"; + diagnostics.globals = [ "vim" ]; + workspace.library = [ ]; # Populated by nixvim + telemetry.enable = false; + }; + }; + }; + + nil_ls.enable = true; # Nix language server + rust_analyzer = { + enable = true; # Rust language server + installCargo = true; + installRustc = true; + }; + pylsp.enable = true; # Python language server + }; + + # Keymaps for LSP actions + keymaps = { + diagnostic = { + "e" = "open_float"; + "[d" = "goto_prev"; + "]d" = "goto_next"; + }; + lspBuf = { + "gd" = "definition"; + "K" = "hover"; + "rn" = "rename"; + "ca" = "code_action"; + }; + }; + }; + + # Autocompletion + cmp = { + enable = true; + autoEnableSources = true; + + settings = { + snippet.expand = '' + function(args) + require('luasnip').lsp_expand(args.body) + end + ''; + + mapping = { + "" = "cmp.mapping.scroll_docs(-4)"; + "" = "cmp.mapping.scroll_docs(4)"; + "" = "cmp.mapping.complete()"; + "" = "cmp.mapping.abort()"; + "" = "cmp.mapping.confirm({ select = true })"; + }; + + sources = [ + { name = "nvim_lsp"; } + { name = "luasnip"; } + { name = "buffer"; } + { name = "path"; } + ]; + }; + }; + + # Snippet engine (required for completion) + luasnip.enable = true; + }; + + # Install LSP servers + extraPackages = with pkgs; [ + lua-language-server + nil + rust-analyzer + python311Packages.python-lsp-server + ]; + }; +} diff --git a/home/neovim/lualine.nix b/home/neovim/lualine.nix new file mode 100644 index 0000000..4f85435 --- /dev/null +++ b/home/neovim/lualine.nix @@ -0,0 +1,22 @@ +{ pkgs, ... }: +{ + # Lualine: Fast and customizable statusline for Neovim + # Displays file info, git status, diagnostics, and mode at the bottom of the editor. + programs.nixvim.plugins.lualine = { + enable = true; + + settings = { + options = { + theme = "catppuccin"; + component_separators = { + left = "|"; + right = "|"; + }; + section_separators = { + left = ""; + right = ""; + }; + }; + }; + }; +} diff --git a/home/neovim/molten.nix b/home/neovim/molten.nix new file mode 100644 index 0000000..6b816ff --- /dev/null +++ b/home/neovim/molten.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: { + programs.nixvim = { + plugins.molten = { + enable = true; + python3Dependencies = p: + with p; [ + pynvim + jupyter-client + cairosvg + ipython + nbformat + ipykernel + pnglatex + plotly + kaleido + pyperclip + ]; + settings = { + kernel_name = "python3"; + auto_open_output = true; + output_win_max_width = 80; + output_win_max_height = 20; + }; + }; + + keymaps = [ + { + mode = "n"; + key = "ml"; + action = "MoltenEvaluateLine"; + options.desc = "Molten: Evaluate line"; + options.silent = true; + } + { + mode = "v"; + key = "mv"; + action = "MoltenEvaluateVisual"; + options.desc = "Molten: Evaluate selection"; + options.silent = true; + } + ]; + }; +} diff --git a/home/neovim/openscad.nix b/home/neovim/openscad.nix new file mode 100644 index 0000000..b4934ab --- /dev/null +++ b/home/neovim/openscad.nix @@ -0,0 +1,28 @@ +{ pkgs, ... }: { + # OpenSCAD: 3D modeling language support with syntax highlighting, + # cheatsheet, snippets, offline manual and fuzzy help + programs.nixvim = { + plugins.openscad = { + enable = true; + autoLoad = true; + settings = { + fuzzy_finder = "fzf"; + auto_open = true; + cheatsheet_toggle_key = "os"; + default_mappings = true; + exec_openscad_trig_key = "oo"; + help_manual_trig_key = "om"; + help_trig_key = "oh"; + top_toggle = "oc"; + + }; + }; + + # Install OpenSCAD binary for preview/compilation + extraPackages = with pkgs; [ + openscad + zathura # PDF viewer for manual + fzf + ]; + }; +} diff --git a/home/neovim/telescope.nix b/home/neovim/telescope.nix new file mode 100644 index 0000000..1d0e330 --- /dev/null +++ b/home/neovim/telescope.nix @@ -0,0 +1,27 @@ +{ pkgs, ... }: +{ + # Telescope: Fuzzy finder for files, buffers, grep, and more + # Provides fast search and navigation throughout your project. + programs.nixvim.plugins.telescope = { + enable = true; + + keymaps = { + "ff" = { + action = "find_files"; + options.desc = "Telescope find files"; + }; + "fg" = { + action = "live_grep"; + options.desc = "Telescope live grep"; + }; + "fb" = { + action = "buffers"; + options.desc = "Telescope buffers"; + }; + "fh" = { + action = "help_tags"; + options.desc = "Telescope help tags"; + }; + }; + }; +} diff --git a/home/neovim/toggleterm.nix b/home/neovim/toggleterm.nix new file mode 100644 index 0000000..3eca8a4 --- /dev/null +++ b/home/neovim/toggleterm.nix @@ -0,0 +1,64 @@ +{ pkgs, ... }: +{ + # ToggleTerm: Terminal emulator inside Neovim + # Provides floating, horizontal, and vertical terminal windows. + programs.nixvim.plugins.toggleterm = { + enable = true; + + settings = { + size = 20; + open_mapping = "[[]]"; + direction = "float"; + float_opts = { + border = "single"; + width = 200; + height = 40; + }; + }; + }; + + programs.nixvim.keymaps = [ + { + mode = "n"; + key = "h"; + action.__raw = '' + function() + require("toggleterm").toggle(1, 10, vim.loop.cwd(), "horizontal") + end + ''; + options.desc = "Toggle terminal (horizontal)"; + } + { + mode = "n"; + key = "v"; + action.__raw = '' + function() + require("toggleterm").toggle(2, 60, vim.loop.cwd(), "vertical") + end + ''; + options.desc = "Toggle terminal (vertical)"; + } + { + mode = "n"; + key = "ft"; + action.__raw = '' + function() + require("toggleterm").toggle(3, 20, vim.loop.cwd(), "float") + end + ''; + options.desc = "Toggle terminal (float)"; + } + { + mode = "t"; + key = ""; + action = "ToggleTerm"; + options.desc = "Toggle terminal"; + } + { + mode = "t"; + key = ""; + action = "v"; + options.desc = "Exit terminal and enter visual mode"; + } + ]; +} diff --git a/home/neovim/treesitter.nix b/home/neovim/treesitter.nix new file mode 100644 index 0000000..58e174a --- /dev/null +++ b/home/neovim/treesitter.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: +{ + + # Install language parsers declaratively + # Syntax Highlighting + programs.nixvim.plugins.treesitter = { + enable = true; + grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [ + lua + nix + python + javascript + rust + rasi + ]; + + settings = { + highlight = { + enable = true; + additional_vim_regex_highlighting = false; + }; + }; + }; +} diff --git a/home/neovim/which-key.nix b/home/neovim/which-key.nix new file mode 100644 index 0000000..ade48c6 --- /dev/null +++ b/home/neovim/which-key.nix @@ -0,0 +1,94 @@ +{ pkgs, ... }: { + # Which-key: Display available keybindings in popup + # Shows all possible key combinations after pressing leader or other prefix keys + programs.nixvim.plugins.which-key = { + enable = true; + + settings = { + delay = 500; # Time in ms before popup shows + + icons = { + breadcrumb = "»"; + separator = "➜"; + group = "+"; + }; + + # Organize keymaps into named groups + spec = [ + # Leader key groups + { + __unkeyed-1 = "a"; + group = "Avante AI"; + icon = "🤖"; + } + { + __unkeyed-1 = "f"; + group = "Find/Files/Terminal"; + icon = "🔍"; + } + { + __unkeyed-1 = "m"; + group = "Molten (Jupyter)"; + icon = "📓"; + } + { + __unkeyed-1 = "o"; + group = "OpenSCAD"; + icon = "🔧"; + } + + # Bracket navigation groups + { + __unkeyed-1 = "["; + group = "Previous"; + icon = "⬅️"; + } + { + __unkeyed-1 = "]"; + group = "Next"; + icon = "➡️"; + } + + # g prefix groups + { + __unkeyed-1 = "g"; + group = "Go/LSP"; + icon = "🎯"; + } + { + __unkeyed-1 = "gr"; + group = "LSP References/Rename"; + icon = "🔗"; + } + { + __unkeyed-1 = "gc"; + group = "Comments"; + icon = "💬"; + } + + # l prefix + { + __unkeyed-1 = "l"; + group = "Live Server"; + icon = "🌐"; + } + + # z prefix + { + __unkeyed-1 = "z"; + group = "Folds/Spell"; + icon = "📋"; + } + ]; + + # Hide specific mappings to reduce clutter + disable = { + builtin_keys = { + # Hide these default vim keys from which-key + i = [ "" "" ]; + n = [ "" ]; + }; + }; + }; + }; +} diff --git a/home/neovim/yazi.nix b/home/neovim/yazi.nix new file mode 100644 index 0000000..06d6e0a --- /dev/null +++ b/home/neovim/yazi.nix @@ -0,0 +1,41 @@ +{ pkgs, ... }: { + # Yazi: Terminal file manager integration for Neovim + # Provides a fast, visual way to browse and manage files. + programs.nixvim = { + # Use extraPlugins to manually load yazi.nvim + extraPlugins = with pkgs.vimPlugins; [ yazi-nvim ]; + + # Configure yazi after it's loaded + extraConfigLua = '' + require('yazi').setup({ + open_for_directories = true, + }) + ''; + + keymaps = [ + { + mode = "n"; + key = "fy"; + action.__raw = '' + function() + require('yazi').yazi(nil, vim.loop.cwd()) + end + ''; + options.desc = "Open Yazi file manager"; + } + { + mode = "n"; + key = "fd"; + action.__raw = '' + function() + require('yazi').yazi(nil, vim.fn.expand("%:p:h")) + end + ''; + options.desc = "Open Yazi in current file directory"; + } + ]; + + # Install yazi terminal program + extraPackages = with pkgs; [ yazi ]; + }; +} diff --git a/home/nixcord.nix b/home/nixcord.nix new file mode 100644 index 0000000..171e6aa --- /dev/null +++ b/home/nixcord.nix @@ -0,0 +1,32 @@ +{ lib, ... }: { + programs.nixcord = { + enable = true; + discord = lib.mkForce { enable = false; }; + vesktop.enable = true; + + config = { + useQuickCss = true; + themeLinks = [ + "https://raw.githubusercontent.com/catppuccin/discord/refs/heads/main/themes/mocha.theme.css" + ]; + frameless = true; + plugins = { + betterFolders.enable = true; + betterRoleContext.enable = true; + mentionAvatars.enable = true; + # copyUserURLs.enable = true; + fakeNitro.enable = true; + decor.enable = true; + accountPanelServerProfile.enable = true; + copyFileContents.enable = true; + fakeProfileThemes.enable = true; + friendsSince.enable = true; + implicitRelationships.enable = true; + # noTrack.enable = true; + permissionsViewer.enable = true; + serverInfo.enable = true; + translate.enable = true; + }; + }; + }; +} diff --git a/home/obsidian.nix b/home/obsidian.nix new file mode 100644 index 0000000..e5e84e5 --- /dev/null +++ b/home/obsidian.nix @@ -0,0 +1,4 @@ +_: { + # TODO: Add Automatic Vault pull and detection + programs.obsidian.enable = true; +} diff --git a/home/onlyoffice.nix b/home/onlyoffice.nix new file mode 100644 index 0000000..94d72fd --- /dev/null +++ b/home/onlyoffice.nix @@ -0,0 +1 @@ +_: { programs.onlyoffice.enable = true; } diff --git a/home/packages.nix b/home/packages.nix new file mode 100644 index 0000000..fefe365 --- /dev/null +++ b/home/packages.nix @@ -0,0 +1,61 @@ +{ pkgs, ... }: +{ + home = { + packages = with pkgs; [ + # dev tools + curl + wget + btop + tree + ripgrep + pciutils + usbutils + nvme-cli + nmap + iperf3 + lm_sensors + file + which + libnotify + jq + yq-go + + # encryption + age + ssh-to-age + + # GUI + openscad + element-desktop + zapzap + # audacity + blender + fstl + nautilus + swayimg + okular + gnumeric + sqlitebrowser + thunderbird + xonotic + + # PDF Tools + pandoc + + # misc + yt-dlp + ffmpeg + + # Archives + zip + unzip + xz + zstd + gnutar + unrar + + # Nix tools + nix-index + ]; + }; +} diff --git a/home/python.nix b/home/python.nix new file mode 100644 index 0000000..be4b85d --- /dev/null +++ b/home/python.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: { + home.packages = with pkgs; [ + # Python 3.13 (newest stable) + python313 + python313Packages.pip + python313Packages.virtualenv + + # Additional useful tools + python313Packages.pipx # Install Python apps in isolated environments + uv # Fast Python package installer (alternative to pip) + ]; + + # Set up default Python version + home.sessionVariables = { PYTHON = "${pkgs.python313}/bin/python3"; }; + + # Shell aliases for convenience + programs.zsh.shellAliases = { + venv = "python3 -m venv"; + activate = "source venv/bin/activate"; + }; + + programs.fish.shellAliases = { + venv = "python3 -m venv"; + activate = "source venv/bin/activate.fish"; + }; +} diff --git a/home/shell.nix b/home/shell.nix new file mode 100644 index 0000000..c0b73c2 --- /dev/null +++ b/home/shell.nix @@ -0,0 +1,210 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + eza # ls replacement + fzf # FuzzyFinder + tdf # terminal pdf viewer + jq # json parser + tree + fastfetch # system stats + tabiew # Table viewer + glow # MD Viewer + + llm # LLM in the Terminal + + # Fun stuff + zoxide + lolcat + cmatrix + ]; + + programs.kitty = { + enable = true; + themeFile = "Catppuccin-Mocha"; + + font = { + name = "Fira Code Nerd Font"; + size = 12; + }; + + settings = { + confirm_os_window_close = 0; + dynamic_background_opacity = true; # ctrl+shift+a>m/l + enable_audio_bell = false; + mouse_hide_wait = 3.0; + window_padding_width = 10; + + background_opacity = 0.8; + background_blur = 5; + + tab_bar_min_tabs = 1; + tab_bar_edge = "bottom"; + tab_bar_style = "custom"; # Should be changed to custom + tab_title_template = "{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{title}"; + + symbol_map = + let + mappings = [ + "U+23FB-U+23FE" + "U+2B58" + "U+E200-U+E2A9" + "U+E0A0-U+E0A3" + "U+E0B0-U+E0BF" + "U+E0C0-U+E0C8" + "U+E0CC-U+E0CF" + "U+E0D0-U+E0D2" + "U+E0D4" + "U+E700-U+E7C5" + "U+F000-U+F2E0" + "U+2665" + "U+26A1" + "U+F400-U+F4A8" + "U+F67C" + "U+E000-U+E00A" + "U+F300-U+F313" + "U+E5FA-U+E62B" + ]; + in + (builtins.concatStringsSep "," mappings) + " Symbols Nerd Font Mono"; + }; + }; + + programs.yazi = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + enableFishIntegration = true; + + settings = { + ration = [ + 1 + 3 + 4 + ]; + }; + }; + + programs.zsh = { + enable = true; + enableCompletion = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + + shellAliases = { + ls = "eza"; + la = "eza -la"; + f = "fzf"; + i = "kitty +kitten icat"; + "nix-switch" = "sudo darwin-rebuild switch --flake ~/.config/nix#cyper-mac"; + }; + + initContent = '' + fastfetch + ai() { + llm -m groq/groq/compound "$@" | glow + } + ''; + }; + + programs.fish = { + enable = true; + + shellAliases = { + ls = "eza"; + la = "eza -la"; + f = "fzf"; + i = "kitty +kitten icat"; + "nix-switch" = "sudo nixos-rebuild switch --flake ~/.config/nix#$(hostname)"; + }; + + interactiveShellInit = '' + starship init fish | source + fzf --fish | source + function fish_greeting + fastfetch + end + ''; + + functions.ai = { + body = '' + llm -m groq/groq/compound $argv | glow + ''; + }; + }; + + programs.starship = { + enable = true; + settings = { + add_newline = true; + command_timeout = 500; + + format = '' + $username$hostname $directory $git_branch$git_status + $character ''; + right_format = "$cmd_duration"; + + username = { + style_user = "bold #cba6f7"; + style_root = "bold #f38ba8"; + format = "[┌](bold #a6e3a1)[$user]($style)"; + show_always = true; + }; + + hostname = { + style = "bold #74c7ec"; + format = "[@](bold #fab387)[$hostname]($style)"; + ssh_only = false; + }; + + directory = { + style = "bold #a6e3a1"; + truncation_length = 0; + truncation_symbol = ""; + format = "[⤇ ](bold #f38ba8)[《$path 》]($style)"; + }; + + git_branch = { + format = "[⟦$branch⟧]($style)"; + style = "bold #f9e2af"; + }; + + # Git status module settings + git_status = { + format = "[[(*$conflicted$untracked$modified$staged$renamed$deleted)](red) ($ahead_behind$stashed)]($style)"; + style = "bold #a6e3a1"; + conflicted = ""; + untracked = ""; + modified = ""; + staged = ""; + renamed = ""; + deleted = ""; + }; + + # Command duration module + cmd_duration = { + format = "[$duration]($style)"; + style = "bold #cdd6f4"; + min_time = 5000; # Only show if command takes longer than 5 seconds + }; + + # Character module (prompt symbol) + character = { + success_symbol = "[└──────⇴ ](bold #a6e3a1)"; + error_symbol = "[└──────⇴ ](bold #f38ba8)"; + }; + + nix_shell = { + format = "[$symbol$state( ($name))]($style)"; + symbol = "U+02744"; + style = "bold #89dceb"; + }; + }; + }; + + home.file = { + ".config/fastfetch/config.jsonc".source = ./fastfetch.jsonc; + ".config/tabiew/theme.toml".source = ./tabiew.toml; + ".config/kitty/tab_bar.py".source = ./tab_bar.py; + ".hushlogin".text = ""; # Suppress login + }; +} diff --git a/home/spicetify.nix b/home/spicetify.nix new file mode 100644 index 0000000..4eab067 --- /dev/null +++ b/home/spicetify.nix @@ -0,0 +1,32 @@ +{ pkgs, inputs, ... }: { + programs.spicetify = + let spicePkgs = inputs.spicetify-nix.legacyPackages.${pkgs.system}; + in { + enable = true; + spotifyPackage = pkgs.spotify; + theme = spicePkgs.themes.catppuccin; + colorScheme = "mocha"; + + enabledExtensions = with spicePkgs.extensions; [ + bookmark + fullAppDisplay + keyboardShortcut + popupLyrics + shuffle + autoVolume + betterGenres + adblock + wikify + songStats + ]; + + enabledCustomApps = with spicePkgs.apps; [ + lyricsPlus + newReleases + marketplace + ]; + + #enabledSnippets = with spicePkgs.snippets; [ ]; + + }; +} diff --git a/home/tab_bar.py b/home/tab_bar.py new file mode 100644 index 0000000..e1bad95 --- /dev/null +++ b/home/tab_bar.py @@ -0,0 +1,34 @@ +from datetime import datetime +from kitty.tab_bar import DrawData, ExtraData, TabBarData, as_rgb +from kitty.fast_data_types import Screen + + +def draw_tab( + draw_data: DrawData, + screen: Screen, + tab: TabBarData, + before: int, + max_title_length: int, + index: int, + is_last: bool, + extra_data: ExtraData, +) -> int: + + # Left side: Current directory or command + screen.cursor.fg = as_rgb(int("a6e3a1", 16)) + screen.cursor.bg = as_rgb(int("1e1e2e", 16)) + + # Get the foreground process (command) or use title + title = tab.active_fg or tab.title or "shell" + screen.draw(f" {title} ") + + # Middle: Nix icon + screen.cursor.fg = as_rgb(int("89dceb", 16)) + screen.draw(" ❄ ") + + # Right: Current time + screen.cursor.fg = as_rgb(int("cdd6f4", 16)) + current_time = datetime.now().strftime("%H:%M") + screen.draw(f"{current_time} ") + + return screen.cursor.x diff --git a/home/tabiew.toml b/home/tabiew.toml new file mode 100644 index 0000000..514af60 --- /dev/null +++ b/home/tabiew.toml @@ -0,0 +1,141 @@ +# Catppuccin Mocha Theme for Tabiew +# Base colors from Catppuccin Mocha palette + +[table_header] +fg = "#F5E0DC" # Rosewater +bg = "#181825" # Mantle +add_modifier = "BOLD" +sub_modifier = "" + +[[table_headers]] +fg = "#F5C2E7" # Pink +bg = "#181825" # Mantle +add_modifier = "BOLD" +sub_modifier = "" + +[[table_headers]] +fg = "#CBA6F7" # Mauve +bg = "#181825" # Mantle +add_modifier = "BOLD" +sub_modifier = "" + +[[table_headers]] +fg = "#89DCEB" # Sky +bg = "#181825" # Mantle +add_modifier = "BOLD" +sub_modifier = "" + +[[rows]] +fg = "#CDD6F4" # Text +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[rows]] +fg = "#CDD6F4" # Text +bg = "#181825" # Mantle +add_modifier = "" +sub_modifier = "" + +[highlight] +fg = "#181825" # Mantle +bg = "#F9E2AF" # Yellow +add_modifier = "BOLD" +sub_modifier = "" + +[[table_tags]] +fg = "#181825" # Mantle +bg = "#F38BA8" # Red +add_modifier = "BOLD" +sub_modifier = "" + +[[table_tags]] +fg = "#181825" # Mantle +bg = "#A6E3A1" # Green +add_modifier = "BOLD" +sub_modifier = "" + +[block] +fg = "#FAB387" # Peach +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[block_tag] +fg = "#181825" # Mantle +bg = "#FAB387" # Peach +add_modifier = "BOLD" +sub_modifier = "" + +[text] +fg = "#CDD6F4" # Text +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[subtext] +fg = "#9399B2" # Overlay1 +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[error] +fg = "#CDD6F4" # Text +bg = "#F38BA8" # Red +add_modifier = "BOLD" +sub_modifier = "" + +[[chart]] +fg = "#F38BA8" # Red +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#FAB387" # Peach (Orange) +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#F9E2AF" # Yellow +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#A6E3A1" # Green +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#94E2D5" # Teal +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#89DCEB" # Sky (Cyan) +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#89B4FA" # Blue +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#CBA6F7" # Mauve (Purple) +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + +[[chart]] +fg = "#F5C2E7" # Pink +bg = "#313244" # Surface0 +add_modifier = "" +sub_modifier = "" + diff --git a/home/xdg.nix b/home/xdg.nix new file mode 100644 index 0000000..e6ddaf7 --- /dev/null +++ b/home/xdg.nix @@ -0,0 +1,94 @@ +{ pkgs, config, ... }: +let + browser = [ "floorp.desktop" ]; + + # XDG MIME types + associations = { + "application/x-extension-htm" = browser; + "application/x-extension-html" = browser; + "application/x-extension-shtml" = browser; + "application/x-extension-xht" = browser; + "application/x-extension-xhtml" = browser; + "application/xhtml+xml" = browser; + "text/html" = browser; + "x-scheme-handler/about" = browser; + "x-scheme-handler/chrome" = [ "chromium-browser.desktop" ]; + "x-scheme-handler/ftp" = browser; + "x-scheme-handler/http" = browser; + "x-scheme-handler/https" = browser; + "x-scheme-handler/unknown" = browser; + + "audio/*" = [ "mpv.desktop" ]; + "video/*" = [ "mpv.desktop" ]; + "image/*" = [ "swayimg.desktop" ]; + #"application/json" = browser; + "application/pdf" = [ "okular.desktop" ]; + "x-scheme-handler/discord" = [ "discordcanary.desktop" ]; + "x-scheme-handler/spotify" = [ "spotify.desktop" ]; + "x-scheme-handler/tg" = [ "telegramdesktop.desktop" ]; + + "text/csv" = [ "gnumeric.desktop" ]; + "application/csv" = [ "gnumeric.desktop" ]; + "text/tab-separated-values" = [ "gnumeric.desktop" ]; + "application/tsv" = [ "gnumeric.desktop" ]; + "application/json" = [ "kitty-tabiew.desktop" ]; + "application/x-ndjson" = [ "kitty-tabiew.desktop" ]; + "application/vnd.apache.arrow.file" = [ "kitty-tabiew.desktop" ]; + "application/parquet" = [ "kitty-tabiew.desktop" ]; + "application/x-parquet" = [ "kitty-tabiew.desktop" ]; + "application/vnd.sqlite3" = [ "sqlitebrowser.desktop" ]; + "application/x-sqlite3" = [ "sqlitebrowser.desktop" ]; + "application/fwf" = [ "kitty-tabiew.desktop" ]; + "text/fwf" = [ "kitty-tabiew.desktop" ]; + + }; +in +{ + xdg = { + enable = true; + cacheHome = config.home.homeDirectory + "/.local/cache"; + + mimeApps = { + enable = true; + defaultApplications = associations; + }; + + desktopEntries = { + kitty-tabiew = { + name = "Tabiew CSV Viewer"; + exec = "kitty -e tw %F --theme catppuccin"; + terminal = false; + type = "Application"; + mimeType = [ + "text/csv" + "application/csv" + "text/tab-separated-values" + "application/tsv" + "application/json" + "application/x-ndjson" + "application/vnd.apache.arrow.file" + "application/parquet" + "application/x-parquet" + "application/vnd.sqlite3" + "application/x-sqlite3" + "application/fwf" + "text/fwf" + ]; + categories = [ + "Utility" + "Viewer" + "Database" + "Development" + ]; + }; + }; + + userDirs = { + enable = true; + createDirectories = true; + extraConfig = { + XDG_SCREENSHOTS_DIR = "${config.xdg.userDirs.pictures}/Screenshots"; + }; + }; + }; +} diff --git a/hosts/cyper-desktop/configuration.nix b/hosts/cyper-desktop/configuration.nix new file mode 100644 index 0000000..31cb060 --- /dev/null +++ b/hosts/cyper-desktop/configuration.nix @@ -0,0 +1,31 @@ +{ + imports = [ ./hardware-configuration.nix ]; + + networking = { + useNetworkd = true; + useDHCP = false; + firewall.enable = true; + }; + + systemd.network = { + enable = true; + networks."10-ethernet" = { + matchConfig.Name = "eno1"; + networkConfig = { + Address = "192.168.2.40/24"; + Gateway = "192.168.2.1"; + DNS = "192.168.2.2"; + DHCP = "no"; + }; + }; + }; + + boot.loader = { + systemd-boot = { + enable = true; + configurationLimit = 10; + editor = false; + }; + efi.canTouchEfiVariables = true; + }; +} diff --git a/hosts/cyper-desktop/hardware-configuration.nix b/hosts/cyper-desktop/hardware-configuration.nix new file mode 100644 index 0000000..ada95d2 --- /dev/null +++ b/hosts/cyper-desktop/hardware-configuration.nix @@ -0,0 +1,67 @@ +{ + config, + lib, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + ]; + kernelModules = [ ]; + }; + kernelModules = [ + "kvm-intel" + "v4l2loopback" + ]; + extraModulePackages = [ config.boot.kernelPackages.v4l2loopback.out ]; + extraModprobeConfig = '' + options v4l2loopback exclusive_caps=1 card_label="Virtual Camera" + ''; + }; + + fileSystems = { + "/" = { + device = "/dev/disk/by-label/NIXROOT"; + fsType = "ext4"; + }; + + "/boot" = { + device = "/dev/disk/by-label/NIXBOOT"; + fsType = "vfat"; + options = [ + "fmask=0022" + "dmask=0022" + ]; + }; + + "/storage" = { + device = "/dev/disk/by-label/STORAGE"; + fsType = "ext4"; + }; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + + hardware = { + cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + graphics = { + enable = true; + enable32Bit = true; + }; + }; +} diff --git a/nixos/audio.nix b/nixos/audio.nix new file mode 100644 index 0000000..de9a862 --- /dev/null +++ b/nixos/audio.nix @@ -0,0 +1,14 @@ +{ ... }: +{ + services.pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + pulse.enable = true; + #jack.enable = true; # audio production + }; + + }; + security.rtkit.enable = true; +} diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..c5f6089 --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,101 @@ +{ + pkgs, + inputs, + primaryUser, + ... +}: +{ + imports = [ + ./fonts.nix + ./sops.nix + ./regreet.nix + ./plymouth + ./audio.nix + ./ssh.nix + ./locale.nix + ./tailscale.nix + ./virt.nix + ./webcam.nix + ]; + + # nix config + nix = { + settings = { + experimental-features = [ + "nix-command" + "flakes" + ]; + max-jobs = "auto"; + cores = 0; + substituters = [ + "https://hyprland.cachix.org" + "https://nix-community.cachix.org" + ]; + trusted-public-keys = [ + "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + }; + + # Garbage collection + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + # Disable Docs + documentation = { + enable = true; + doc.enable = false; # Skip large documentation + man.enable = true; # Keep man pages + info.enable = false; # Skip info pages + }; + + nixpkgs.config = { + allowUnfree = true; + }; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + users.${primaryUser} = { + imports = [ ../home ]; + }; + extraSpecialArgs = { inherit inputs primaryUser; }; + }; + + programs = { + fish.enable = true; + hyprland = { + enable = true; + package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland; + }; + steam.enable = true; + dconf.enable = true; + appimage = { + enable = true; + binfmt = true; + }; + }; + + security = { + pam.services.swaylock = { }; + polkit.enable = true; + apparmor.enable = true; + }; + + users.users.${primaryUser} = { + home = "/home/${primaryUser}"; + shell = pkgs.fish; + isNormalUser = true; + openssh.authorizedKeys.keyFiles = [ ./ssh-key ]; + extraGroups = [ + "wheel" + "video" + "audio" + "libvirtd" + ]; + }; +} diff --git a/nixos/fonts.nix b/nixos/fonts.nix new file mode 100644 index 0000000..e0eae03 --- /dev/null +++ b/nixos/fonts.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: +{ + fonts.packages = with pkgs; [ + nerd-fonts.fira-code + nerd-fonts.fira-mono + nerd-fonts.hack + ]; +} diff --git a/nixos/locale.nix b/nixos/locale.nix new file mode 100644 index 0000000..8cee5af --- /dev/null +++ b/nixos/locale.nix @@ -0,0 +1,18 @@ +{ ... }: +{ + time.timeZone = "Europe/Berlin"; + i18n = { + defaultLocale = "en_US.UTF-8"; + extraLocaleSettings = { + LC_ADDRESS = "de_DE.UTF-8"; + LC_IDENTIFICATION = "de_DE.UTF-8"; + LC_MEASUREMENT = "de_DE.UTF-8"; + LC_MONETARY = "de_DE.UTF-8"; + LC_NAME = "de_DE.UTF-8"; + LC_NUMERIC = "de_DE.UTF-8"; + LC_PAPER = "de_DE.UTF-8"; + LC_TELEPHONE = "de_DE.UTF-8"; + LC_TIME = "de_DE.UTF-8"; + }; + }; +} diff --git a/nixos/plymouth/default.nix b/nixos/plymouth/default.nix new file mode 100644 index 0000000..c2df556 --- /dev/null +++ b/nixos/plymouth/default.nix @@ -0,0 +1,36 @@ +{ pkgs, ... }: +let + mikuTheme = pkgs.stdenv.mkDerivation { + name = "plymouth-theme-miku"; + src = ./miku; + installPhase = '' + mkdir -p $out/share/plymouth/themes/miku/frames + cp miku.plymouth $out/share/plymouth/themes/miku/ + cp miku.script $out/share/plymouth/themes/miku/ + cp images/frames/*.png $out/share/plymouth/themes/miku/frames/ + ''; + }; +in +{ + boot = { + plymouth = { + enable = true; + theme = "miku"; + themePackages = [ + mikuTheme + ]; + }; + + # Enable "Silent boot" + consoleLogLevel = 3; + initrd.verbose = false; + kernelParams = [ + "quiet" + "splash" + "boot.shell_on_fail" + "udev.log_priority=3" + "rd.systemd.show_status=auto" + ]; + loader.timeout = 0; + }; +} diff --git a/nixos/plymouth/miku/images/frames/frame_0000.png b/nixos/plymouth/miku/images/frames/frame_0000.png new file mode 100644 index 0000000..7bbf5a3 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0000.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0001.png b/nixos/plymouth/miku/images/frames/frame_0001.png new file mode 100644 index 0000000..acdcff0 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0001.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0002.png b/nixos/plymouth/miku/images/frames/frame_0002.png new file mode 100644 index 0000000..3e4c5fa Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0002.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0003.png b/nixos/plymouth/miku/images/frames/frame_0003.png new file mode 100644 index 0000000..dd386fe Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0003.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0004.png b/nixos/plymouth/miku/images/frames/frame_0004.png new file mode 100644 index 0000000..05cf4db Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0004.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0005.png b/nixos/plymouth/miku/images/frames/frame_0005.png new file mode 100644 index 0000000..462b813 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0005.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0006.png b/nixos/plymouth/miku/images/frames/frame_0006.png new file mode 100644 index 0000000..d4b513b Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0006.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0007.png b/nixos/plymouth/miku/images/frames/frame_0007.png new file mode 100644 index 0000000..230a812 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0007.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0008.png b/nixos/plymouth/miku/images/frames/frame_0008.png new file mode 100644 index 0000000..8ac5eb7 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0008.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0009.png b/nixos/plymouth/miku/images/frames/frame_0009.png new file mode 100644 index 0000000..f582073 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0009.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0010.png b/nixos/plymouth/miku/images/frames/frame_0010.png new file mode 100644 index 0000000..89837d2 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0010.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0011.png b/nixos/plymouth/miku/images/frames/frame_0011.png new file mode 100644 index 0000000..6f67ca6 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0011.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0012.png b/nixos/plymouth/miku/images/frames/frame_0012.png new file mode 100644 index 0000000..926dc24 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0012.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0013.png b/nixos/plymouth/miku/images/frames/frame_0013.png new file mode 100644 index 0000000..af6aff5 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0013.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0014.png b/nixos/plymouth/miku/images/frames/frame_0014.png new file mode 100644 index 0000000..c4bd0d9 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0014.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0015.png b/nixos/plymouth/miku/images/frames/frame_0015.png new file mode 100644 index 0000000..34a8772 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0015.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0016.png b/nixos/plymouth/miku/images/frames/frame_0016.png new file mode 100644 index 0000000..d99e535 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0016.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0017.png b/nixos/plymouth/miku/images/frames/frame_0017.png new file mode 100644 index 0000000..c30636c Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0017.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0018.png b/nixos/plymouth/miku/images/frames/frame_0018.png new file mode 100644 index 0000000..cef6693 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0018.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0019.png b/nixos/plymouth/miku/images/frames/frame_0019.png new file mode 100644 index 0000000..0cb60d5 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0019.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0020.png b/nixos/plymouth/miku/images/frames/frame_0020.png new file mode 100644 index 0000000..5f0a965 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0020.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0021.png b/nixos/plymouth/miku/images/frames/frame_0021.png new file mode 100644 index 0000000..9116477 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0021.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0022.png b/nixos/plymouth/miku/images/frames/frame_0022.png new file mode 100644 index 0000000..c83099f Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0022.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0023.png b/nixos/plymouth/miku/images/frames/frame_0023.png new file mode 100644 index 0000000..67c9815 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0023.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0024.png b/nixos/plymouth/miku/images/frames/frame_0024.png new file mode 100644 index 0000000..c71d4a2 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0024.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0025.png b/nixos/plymouth/miku/images/frames/frame_0025.png new file mode 100644 index 0000000..7f48368 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0025.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0026.png b/nixos/plymouth/miku/images/frames/frame_0026.png new file mode 100644 index 0000000..b546238 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0026.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0027.png b/nixos/plymouth/miku/images/frames/frame_0027.png new file mode 100644 index 0000000..2e233bf Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0027.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0028.png b/nixos/plymouth/miku/images/frames/frame_0028.png new file mode 100644 index 0000000..4948e3d Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0028.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0029.png b/nixos/plymouth/miku/images/frames/frame_0029.png new file mode 100644 index 0000000..e4ae9e7 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0029.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0030.png b/nixos/plymouth/miku/images/frames/frame_0030.png new file mode 100644 index 0000000..88ce3af Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0030.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0031.png b/nixos/plymouth/miku/images/frames/frame_0031.png new file mode 100644 index 0000000..93d9111 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0031.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0032.png b/nixos/plymouth/miku/images/frames/frame_0032.png new file mode 100644 index 0000000..74f9ce2 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0032.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0033.png b/nixos/plymouth/miku/images/frames/frame_0033.png new file mode 100644 index 0000000..16bb387 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0033.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0034.png b/nixos/plymouth/miku/images/frames/frame_0034.png new file mode 100644 index 0000000..01631bb Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0034.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0035.png b/nixos/plymouth/miku/images/frames/frame_0035.png new file mode 100644 index 0000000..dedbd06 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0035.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0036.png b/nixos/plymouth/miku/images/frames/frame_0036.png new file mode 100644 index 0000000..8dd2442 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0036.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0037.png b/nixos/plymouth/miku/images/frames/frame_0037.png new file mode 100644 index 0000000..56c96bd Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0037.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0038.png b/nixos/plymouth/miku/images/frames/frame_0038.png new file mode 100644 index 0000000..69d3bef Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0038.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0039.png b/nixos/plymouth/miku/images/frames/frame_0039.png new file mode 100644 index 0000000..8341a80 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0039.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0040.png b/nixos/plymouth/miku/images/frames/frame_0040.png new file mode 100644 index 0000000..107a51d Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0040.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0041.png b/nixos/plymouth/miku/images/frames/frame_0041.png new file mode 100644 index 0000000..17b5d06 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0041.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0042.png b/nixos/plymouth/miku/images/frames/frame_0042.png new file mode 100644 index 0000000..e449590 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0042.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0043.png b/nixos/plymouth/miku/images/frames/frame_0043.png new file mode 100644 index 0000000..ba279e5 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0043.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0044.png b/nixos/plymouth/miku/images/frames/frame_0044.png new file mode 100644 index 0000000..cf39369 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0044.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0045.png b/nixos/plymouth/miku/images/frames/frame_0045.png new file mode 100644 index 0000000..55989bb Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0045.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0046.png b/nixos/plymouth/miku/images/frames/frame_0046.png new file mode 100644 index 0000000..5163dcd Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0046.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0047.png b/nixos/plymouth/miku/images/frames/frame_0047.png new file mode 100644 index 0000000..461934f Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0047.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0048.png b/nixos/plymouth/miku/images/frames/frame_0048.png new file mode 100644 index 0000000..f8cf991 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0048.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0049.png b/nixos/plymouth/miku/images/frames/frame_0049.png new file mode 100644 index 0000000..ca84503 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0049.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0050.png b/nixos/plymouth/miku/images/frames/frame_0050.png new file mode 100644 index 0000000..bb804b7 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0050.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0051.png b/nixos/plymouth/miku/images/frames/frame_0051.png new file mode 100644 index 0000000..ff2a631 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0051.png differ diff --git a/nixos/plymouth/miku/images/frames/frame_0052.png b/nixos/plymouth/miku/images/frames/frame_0052.png new file mode 100644 index 0000000..011aea3 Binary files /dev/null and b/nixos/plymouth/miku/images/frames/frame_0052.png differ diff --git a/nixos/plymouth/miku/miku.plymouth b/nixos/plymouth/miku/miku.plymouth new file mode 100644 index 0000000..9b91e87 --- /dev/null +++ b/nixos/plymouth/miku/miku.plymouth @@ -0,0 +1,8 @@ +[Plymouth Theme] +Name=Miku +Description=Hatsune Miku Dancing +ModuleName=Script + +[script] +ImageDir=/usr/share/plymouth/themes/miku +ScriptFile=/usr/share/plymouth/themes/miku/miku.script diff --git a/nixos/plymouth/miku/miku.script b/nixos/plymouth/miku/miku.script new file mode 100644 index 0000000..11149d9 --- /dev/null +++ b/nixos/plymouth/miku/miku.script @@ -0,0 +1,30 @@ +# Screen dimensions +screen_width = Window.GetWidth(); +screen_height = Window.GetHeight(); + +# Load frames +frame_count = 53; +frames = []; +for (i = 0; i < frame_count; i++) { + num = String(i); + if (i < 10) num = "000" + num; + else if (i < 100) num = "00" + num; + else num = "0" + num; + frames[i] = Image("frames/frame_" + num + ".png"); +} + +# Position centered +x = (screen_width - 498) / 2; +y = (screen_height - 498) / 2; + +# Animation state +current_frame = 0; + +fun refresh_callback() { + sprite = Sprite(frames[current_frame]); + sprite.SetX(x); + sprite.SetY(y); + current_frame = (current_frame + 1) % frame_count; +} + +Plymouth.SetRefreshFunction(refresh_callback); diff --git a/nixos/regreet.nix b/nixos/regreet.nix new file mode 100644 index 0000000..40120b9 --- /dev/null +++ b/nixos/regreet.nix @@ -0,0 +1,66 @@ +{ + lib, + ... +}: +{ + environment.etc = { + "greetd/background.png".source = ../assets/wallpapers/lucy_with_cat.png; + "greetd/environments".text = '' + Hyprland + niri-session + fish + ''; + }; + + programs.regreet = { + enable = true; + + cageArgs = [ + "-s" + "-m" + "last" + ]; + + settings = { + + background = { + path = "/etc/greetd/background.png"; + fit = "Fill"; + }; + + GTK = { + application_prefer_dark_theme = true; + cursor_theme_name = lib.mkForce "catppuccin-mocha-dark"; + font_name = lib.mkForce "FiraCode Nerd Font Propo 12"; + icon_theme_name = lib.mkForce "Papirus-Dark"; + theme_name = lib.mkForce "catppuccin-mocha-standard-mauve-dark"; + }; + + commands = { + reboot = [ + "systemctl" + "reboot" + ]; + poweroff = [ + "systemctl" + "poweroff" + ]; + x11_prefix = [ + "startx" + "/usr/bin/env" + ]; + }; + + appearance = { + greeting_msg = "Hey there!"; + }; + + widget.clock = { + format = "%A %d.%m.%Y %T"; + resolution = "500ms"; + timezone = "Europe/Berlin"; + label_width = 150; + }; + }; + }; +} diff --git a/nixos/sops.nix b/nixos/sops.nix new file mode 100644 index 0000000..8e95ed4 --- /dev/null +++ b/nixos/sops.nix @@ -0,0 +1,18 @@ +{ primaryUser, ... }: +{ + sops = { + defaultSopsFile = ../secrets/secrets.yaml; + defaultSopsFormat = "yaml"; + age.keyFile = "/home/phil/.config/sops/age/keys.txt"; + + secrets = { + GROQ_API_KEY = { }; + OPENWEATHER_API_KEY = { }; + ssh_private_key = { + path = "/home/${primaryUser}/.ssh/ssh"; + owner = primaryUser; + mode = "0600"; + }; + }; + }; +} diff --git a/nixos/ssh-key b/nixos/ssh-key new file mode 100644 index 0000000..93d25f7 --- /dev/null +++ b/nixos/ssh-key @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuYuGhqRC/QLoRBH91c3DG5JHlAdRLQsvde18k5ipY2 phil@cyperpunk.de diff --git a/nixos/ssh.nix b/nixos/ssh.nix new file mode 100644 index 0000000..3310f37 --- /dev/null +++ b/nixos/ssh.nix @@ -0,0 +1,14 @@ +{ ... }: +{ + services.openssh = { + enable = true; + openFirewall = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + }; + }; + + programs.ssh.startAgent = true; + +} diff --git a/nixos/tailscale.nix b/nixos/tailscale.nix new file mode 100644 index 0000000..b6d9a8c --- /dev/null +++ b/nixos/tailscale.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + services.tailscale = { + enable = true; + openFirewall = true; + }; +} diff --git a/nixos/virt.nix b/nixos/virt.nix new file mode 100644 index 0000000..127e652 --- /dev/null +++ b/nixos/virt.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + virtualisation.libvirtd.enable = true; + boot.binfmt.emulatedSystems = [ + "aarch64-linux" + "riscv64-linux" + ]; + environment.systemPackages = with pkgs; [ + qemu + quickemu + quickgui + nemu + ]; + systemd.tmpfiles.rules = [ + "L+ /var/lib/qemu/firmware - - - - ${pkgs.qemu}/share/qemu/firmware" + ]; + environment.etc."qemu/bridge.conf".text = '' + allow br0 + ''; +} diff --git a/nixos/webcam.nix b/nixos/webcam.nix new file mode 100644 index 0000000..29bedea --- /dev/null +++ b/nixos/webcam.nix @@ -0,0 +1,27 @@ +{ pkgs, ... }: +{ + services.udev.extraRules = '' + ACTION=="add", \ + SUBSYSTEM=="usb", \ + ATTR{idVendor}=="04a9", \ + ATTR{idProduct}=="31ea", \ + RUN+="systemctl restart webcam" + ''; + + systemd.services.webcam = { + enable = true; + description = "Canon Camera Webcam"; + script = '' + ${pkgs.gphoto2}/bin/gphoto2 --stdout --capture-movie | \ + ${pkgs.ffmpeg}/bin/ffmpeg \ + -i - \ + -vcodec rawvideo \ + -pix_fmt yuv420p \ + -threads 0 \ + -framerate 30 \ + -f v4l2 \ + /dev/video0 + ''; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml new file mode 100644 index 0000000..a84e516 --- /dev/null +++ b/secrets/secrets.yaml @@ -0,0 +1,18 @@ +GROQ_API_KEY: ENC[AES256_GCM,data:OyuC4jfw67sCDa0XBGr78S6pzPV1ruy7KiIqPMgWWcOCVm3Y/khXEYPMjUTGrq9YLOw1MLso0OE=,iv:0y9klMYVtGsqAaLc2JidjZYSLhhbcbWbnBf8sZiC3rM=,tag:r6G2pzZn2d9JIaS+ozKnmg==,type:str] +OPENWEATHER_API_KEY: ENC[AES256_GCM,data:bcuLz70u40nZfNgPTaeNRXdR/zjx0SQjwMbMNNFqROI=,iv:VCzse1a1/k1ZDIpFPL1QhjuS6YaDyohWi61JZaoc0Ws=,tag:UJSNyniNNLfGGRY/uiJcRA==,type:str] +ssh_private_key: ENC[AES256_GCM,data:R511mVFVk1ogAd5CKk/2P6rtT4NnHIFfKyqeCen545QgcvDqDFmW0rFBmPJyipaya2srJNoWvKJbnvxWtTYeJh2tPAybRMoUicStIFMUn3FPNfjx/WuQFLhKLoU3UOHHPJnkFqkQ9MBqLq2k5K7MVsNNFTxIDCKS1jPgkTmAWjRZ0EFiRXLa+Gvnz3GP5ltgfjDwdPeb5xp0/AqKPD8jea9w5ClR6ckrRHCLsfXhL2e9IaF4B96JlIv4rICLX3HmeIgM2PKl2MnSt8we5z39bBoLSA0yWG6BvpiMBaFqbo7jeHf1SxI6R404/emHhwW3pwSCDrq2ZE1ATG2UmA5NssFcVuaBPBoQer+n5haVYMNpNUp6rtKZeAIbf5JEOXJ6CJqiInfnnzOMNGhGFkGUYkhsy3p6Ti/lmNMPX/xtY+8ZqMwXf5drssm5KgnQ5nDbVqnTWAhoT/D3t+cJVAaXGTGw88fU0X95dZr8vaL/5nBCj1uUdv5cRBJ8PGhqbBX8PoiXrtGooBGhxf6nHbxIneSzG1++MZGo3e1G,iv:D1lgCnZKm3Gyv6cZpQ7zGW7JXN5RCwoaas+LroTkhPc=,tag:WI6Nr1cX8gm5pjFpu/Ok0w==,type:str] +sops: + age: + - recipient: age10pyhca0jy75wtqv5hrn0gf0jcam5272zx9h73a8xwwaxyfq89c0qs5dr9t + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMMVVaazhud2paM29JbEJx + aUFnajhSd3NxTzB0MndhRk03WjNvV3BVc0NNCnpxR1pjbXVrZ3RPQkppNHJpQ3pX + dXROb0ZrakE3dmtzbjlqMWFBdWp0RDAKLS0tIHlvbXM4ckx3NkxicVVRSTAzdkN0 + N3I5dzUwc3JtYzczMUhyT04vSHlZamMKT+FzYcDLmlEFYxm/XoBpJb8XaZzBH1v9 + 6fuez+zApathZfl14w41kAUojPWBznnxDqYtNvzVVLXwnpp3BMx+7w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-03-27T10:23:01Z" + mac: ENC[AES256_GCM,data:mRI5VLjUDMhRpR5fmN6MMxaJdbXuMBNcXFX7ItDe1U3H3px+4k0hxhx/anO+VX+Qq4i9kTrqEVkkRY4rzQBEqZaSIlGgzpj4nwdC8469/PBVUCqZ6X47pc+TfG6PP8Iv9nyN+zk4whS+O6c2ZTGVQ+Cok+KIa6r5tlNu/3r85u0=,iv:eK/TDEJctNiMp1eW4b605bvvNHAqBBf6Ybgdg4jQyR4=,tag:D4oW5lTBd1z8Ey0EKhTvmQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.11.0