From 50d930e1ff1e3f5fc3497ad68c7472598da93460 Mon Sep 17 00:00:00 2001 From: DerGrumpf Date: Wed, 11 Feb 2026 11:04:59 +0100 Subject: [PATCH] Init --- README.md | 271 ++++++++++++++++++++++++++++++++++ flake.lock | 257 ++++++++++++++++++++++++++++++++ flake.nix | 45 ++++++ home/default.nix | 20 +++ home/fastfetch.jsonc | 171 +++++++++++++++++++++ home/git.nix | 21 +++ home/neovim/alpha.nix | 147 ++++++++++++++++++ home/neovim/avante.nix | 106 +++++++++++++ home/neovim/catppuccin.nix | 34 +++++ home/neovim/conform.nix | 33 +++++ home/neovim/default.nix | 94 ++++++++++++ home/neovim/lint.nix | 42 ++++++ home/neovim/lsp.nix | 91 ++++++++++++ home/neovim/lualine.nix | 22 +++ home/neovim/molten.nix | 43 ++++++ home/neovim/openscad.nix | 28 ++++ home/neovim/telescope.nix | 27 ++++ home/neovim/toggleterm.nix | 64 ++++++++ home/neovim/treesitter.nix | 24 +++ home/neovim/which-key.nix | 94 ++++++++++++ home/neovim/yazi.nix | 41 +++++ home/packages.nix | 31 ++++ home/python.nix | 26 ++++ home/shell.nix | 203 +++++++++++++++++++++++++ home/tab_bar.py | 34 +++++ home/tabiew.toml | 141 ++++++++++++++++++ hosts/rpi-4/configuration.nix | 12 ++ nixos/default.nix | 53 +++++++ nixos/hardware.nix | 34 +++++ nixos/packages.nix | 19 +++ nixos/settings.nix | 21 +++ 31 files changed, 2249 insertions(+) create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 home/default.nix create mode 100644 home/fastfetch.jsonc create mode 100644 home/git.nix create mode 100644 home/neovim/alpha.nix create mode 100644 home/neovim/avante.nix create mode 100644 home/neovim/catppuccin.nix create mode 100644 home/neovim/conform.nix create mode 100644 home/neovim/default.nix create mode 100644 home/neovim/lint.nix create mode 100644 home/neovim/lsp.nix create mode 100644 home/neovim/lualine.nix create mode 100644 home/neovim/molten.nix create mode 100644 home/neovim/openscad.nix create mode 100644 home/neovim/telescope.nix create mode 100644 home/neovim/toggleterm.nix create mode 100644 home/neovim/treesitter.nix create mode 100644 home/neovim/which-key.nix create mode 100644 home/neovim/yazi.nix create mode 100644 home/packages.nix create mode 100644 home/python.nix create mode 100644 home/shell.nix create mode 100644 home/tab_bar.py create mode 100644 home/tabiew.toml create mode 100644 hosts/rpi-4/configuration.nix create mode 100644 nixos/default.nix create mode 100644 nixos/hardware.nix create mode 100644 nixos/packages.nix create mode 100644 nixos/settings.nix diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae4844e --- /dev/null +++ b/README.md @@ -0,0 +1,271 @@ +# NixOS Starter for Raspberry Pi 4 + +A declarative NixOS flake setup for Raspberry Pi 4, following a modular configuration structure. + +## Directory Structure + +``` +rpi-starter/ +├── flake.nix # Main flake configuration and inputs +├── nixos/ +│ ├── default.nix # Core NixOS system configuration +│ ├── settings.nix # Localization and system preferences +│ ├── hardware.nix # RPi 4 hardware-specific settings +│ └── packages.nix # System-level packages +├── home/ +│ ├── default.nix # Home Manager entry point +│ ├── packages.nix # User packages +│ ├── git.nix # Git configuration +│ └── shell.nix # Zsh, Tmux, Starship configuration +└── hosts/ + └── rpi-4/ + ├── configuration.nix # Host-specific settings + └── shell-functions.sh # Custom shell utilities +``` + +## Quick Start + +### 1. Flash NixOS to SD Card + +```bash +# Download aarch64 image +wget https://hydra.nixos.org/build/XXXXX/download/1/nixos-sd-image-aarch64-linux.img.zst + +# Flash to SD card (replace sdX with your device) +zstdcat nixos-sd-image-aarch64-linux.img.zst | sudo dd of=/dev/sdX bs=4M conv=fsync +``` + +### 2. Boot and Setup Network + +Boot the RPi 4 and find its IP address: + +```bash +arp-scan -l +ssh root@ # Default password is empty +``` + +### 3. Clone Configuration + +```bash +cd /tmp +git clone nixos-config +cd nixos-config +``` + +### 4. Apply Configuration + +```bash +# Switch to new configuration +sudo nixos-rebuild switch --flake .#rpi-4 +``` + +## Customization + +### Change Username + +Edit `flake.nix`: +```nix +primaryUser = "your-username"; # Change from "phil" +``` + +### Add System Packages + +Edit `nixos/packages.nix`: +```nix +environment.systemPackages = with pkgs; [ + # ... existing packages ... + python3 + nodejs +]; +``` + +### Add User Packages + +Edit `home/packages.nix`: +```nix +home.packages = with pkgs; [ + # ... existing packages ... + poetry + nodePackages.pnpm +]; +``` + +### Configure Git + +Edit `home/git.nix`: +```nix +programs.git = { + enable = true; + userName = "Your Name"; + userEmail = "your@email.com"; + # ... more config +}; +``` + +### Customize Shell + +Edit `home/shell.nix` for Zsh, Tmux, and Starship customizations. + +### Add Host-Specific Settings + +Edit `hosts/rpi-4/configuration.nix` for RPi 4-specific packages and settings. + +## Available Commands + +```bash +# Rebuild and switch to new configuration +rebuild + +# Build without switching +rebuild-build + +# Show system health (disk, memory, CPU, temp) +sys-health + +# SSH into RPi +ssh-rpi [user] [host] + +# Update flake inputs +flake-update + +# Show largest directories +du-top +``` + +To use these commands, source the shell functions: + +```bash +source hosts/rpi-4/shell-functions.sh +``` + +Or add to your zsh config to load automatically. + +## Configuration Files Overview + +### flake.nix +- Declares inputs (nixpkgs, home-manager, etc.) +- Defines outputs and system configuration +- Entry point for the entire setup + +### nixos/default.nix +- Main NixOS system configuration +- Imports hardware, settings, and packages modules +- Configures SSH, users, Nix settings + +### nixos/hardware.nix +- RPi 4 bootloader and kernel settings +- Filesystem and swap configuration +- RPi 4-specific hardware enablement + +### nixos/settings.nix +- Timezone and locale settings +- Console keyboard layout +- General system preferences + +### nixos/packages.nix +- System-level packages available to all users + +### home/default.nix +- Home Manager entry point +- Imports shell, git, and packages modules +- Sets home state version + +### home/packages.nix +- User-level packages + +### home/git.nix +- Git configuration (name, email, core settings) + +### home/shell.nix +- Zsh configuration (aliases, keybindings, plugins) +- Tmux configuration (prefix, keybindings) +- Starship prompt setup +- Direnv integration + +### hosts/rpi-4/configuration.nix +- Host-specific package additions +- RPi 4-specific customizations + +### hosts/rpi-4/shell-functions.sh +- Bash functions for common tasks +- Can be sourced in shell configs + +## Locale and Timezone + +Default settings: +- **Timezone**: Europe/Berlin +- **Locale**: en_US.UTF-8 (with German regional settings) + +Change in `nixos/settings.nix`: + +```nix +time.timeZone = "America/New_York"; +i18n.defaultLocale = "en_US.UTF-8"; +``` + +## Troubleshooting + +### SSH Connection Issues +- Ensure SSH is enabled in `nixos/default.nix` +- Check public key is authorized +- Verify hostname resolves: `ping rpi-4.local` + +### Out of Memory +Increase swap in `nixos/hardware.nix`: + +```nix +swapDevices = [{ + device = "/swapfile"; + size = 4096; # Increase to 4GB +}]; +``` + +### Package Not Found +```bash +# Search for a package +nix search nixpkgs package-name + +# Add to appropriate .nix file and rebuild +``` + +### Rebuild Fails +```bash +# Update flake inputs +nix flake update + +# Check for errors +nix flake check +``` + +## Useful Nix Commands + +```bash +# Update all inputs to latest versions +nix flake update + +# Check flake for errors +nix flake check + +# Show flake outputs +nix flake show + +# Search for packages +nix search nixpkgs + +# Inspect package +nix eval -f '' 'hello.meta.description' +``` + +## Resources + +- [NixOS Manual](https://nixos.org/manual/nixos/stable/) +- [Home Manager Manual](https://nix-community.github.io/home-manager/) +- [Nix Flakes Guide](https://nixos.wiki/wiki/Flakes) +- [RPi NixOS Guide](https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi) + +## Notes + +- State version: `24.11` - update if needed +- Store auto-optimizes weekly and cleans packages older than 30 days +- Flakes and nix-command are enabled by default +- Change `primaryUser` from "phil" to your username diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f20ddec --- /dev/null +++ b/flake.lock @@ -0,0 +1,257 @@ +{ + "nodes": { + "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" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1770654520, + "narHash": "sha256-mg5WZMIPGsFu9MxSrUcuJUPMbfMsF77el5yb/7rc10k=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "6c4fdbe1ad198fac36c320fd45c5957324a80b8e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "nixcord": { + "inputs": { + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1770711111, + "narHash": "sha256-fwqwewKc+TGDz593PzfA3YCzZRYdmYDWk6pRTaRNPWg=", + "owner": "kaylorben", + "repo": "nixcord", + "rev": "b3f36f48d83a78653b86b4fe997ff1fccae38c6d", + "type": "github" + }, + "original": { + "owner": "kaylorben", + "repo": "nixcord", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1769089682, + "narHash": "sha256-9yA/LIuAVQq0lXelrZPjLuLVuZdm03p8tfmHhnDIkms=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "078d69f03934859a181e81ba987c2bb033eebfc5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1770537093, + "narHash": "sha256-pF1quXG5wsgtyuPOHcLfYg/ft/QMr8NnX0i6tW2187s=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "fef9403a3e4d31b0a23f0bacebbec52c248fbb51", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1770380644, + "narHash": "sha256-P7dWMHRUWG5m4G+06jDyThXO7kwSk46C1kgjEWcybkE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ae67888ff7ef9dff69b3cf0cc0fbfbcd3a722abe", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1770197578, + "narHash": "sha256-AYqlWrX09+HvGs8zM6ebZ1pwUqjkfpnv8mewYwAo+iM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "00c21e4c93d963c50d4c0c89bfa84ed6e0694df2", + "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": 1770630823, + "narHash": "sha256-5SEmOnJ61vmbap39vzWEsCX5UQ+3Ul8J4mXWKdqSn3w=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "6acc964664ac916c64fe4e394edd467af4d90790", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixcord": "nixcord", + "nixpkgs": "nixpkgs_2", + "nixvim": "nixvim", + "spicetify-nix": "spicetify-nix" + } + }, + "spicetify-nix": { + "inputs": { + "nixpkgs": "nixpkgs_4", + "systems": "systems_2" + }, + "locked": { + "lastModified": 1770528352, + "narHash": "sha256-KO51BALxgLUlhg1CqQgA3Rj8vgAcDvoLxzNLTxD65cc=", + "owner": "Gerg-L", + "repo": "spicetify-nix", + "rev": "9f4ab243968118026f4ff82f7ce41d30319e2bf0", + "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..1930e8b --- /dev/null +++ b/flake.nix @@ -0,0 +1,45 @@ +{ + description = "NixOS Configuration for Raspberry Pi 4"; + + nixConfig = { + extra-substituters = [ "https://nix-community.cachix.org" ]; + extra-trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + + http-connections = 4; + download-buffer-size = 268435456; # 256MB + }; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + home-manager.url = "github:nix-community/home-manager/master"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + nixvim.url = "github:nix-community/nixvim"; + nixcord.url = "github:kaylorben/nixcord"; + spicetify-nix.url = "github:Gerg-L/spicetify-nix"; + }; + + outputs = { self, nixpkgs, home-manager, nixvim, ... }@inputs: + let + primaryUser = "phil"; + system = "aarch64-linux"; + in + { + nixosConfigurations."rpi-4" = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./nixos/default.nix + ./nixos/hardware.nix + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.${primaryUser} = import ./home/default.nix; + home-manager.extraSpecialArgs = { inherit inputs primaryUser; }; + } + ]; + specialArgs = { inherit inputs self primaryUser; }; + }; + }; +} diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..c5d25ef --- /dev/null +++ b/home/default.nix @@ -0,0 +1,20 @@ +{ primaryUser, inputs, ... }: { + imports = [ + ./packages.nix + ./git.nix + ./shell.nix + + inputs.nixvim.homeModules.nixvim + ./neovim + ./python.nix + + ]; + + home = { + username = primaryUser; + stateVersion = "25.11"; + sessionVariables = { + GROQ_API_KEY = "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"; + }; + }; +} diff --git a/home/fastfetch.jsonc b/home/fastfetch.jsonc new file mode 100644 index 0000000..fa90e1b --- /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": "nixos", + // "height": 15, + "width": 12, + "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/git.nix b/home/git.nix new file mode 100644 index 0000000..4ce2355 --- /dev/null +++ b/home/git.nix @@ -0,0 +1,21 @@ +{ primaryUser, ... }: +{ + 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..271ab5d --- /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 + black + rustfmt + prettierd + ]; + }; +} diff --git a/home/neovim/default.nix b/home/neovim/default.nix new file mode 100644 index 0000000..167adb6 --- /dev/null +++ b/home/neovim/default.nix @@ -0,0 +1,94 @@ +{ ... }: { + 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 + ./which-key.nix + ]; + + 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/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/packages.nix b/home/packages.nix new file mode 100644 index 0000000..31c73e4 --- /dev/null +++ b/home/packages.nix @@ -0,0 +1,31 @@ +{ pkgs, ... }: { + home = { + packages = with pkgs; [ + # dev tools + curl + wget + vim + htop + tree + ripgrep + gh # Move to git + zoxide # Move to fish + unrar + + # programming languages + #mise # node, deno, bun, rust, python, etc. + + # PDF Tools + pandoc + texlive.combined.scheme-full + wkhtmltopdf + + # misc + nil # move to nixvim + biome # move to nixvim + nixfmt-rfc-style # move to nixvim + yt-dlp + ffmpeg + ]; + }; +} 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..161f883 --- /dev/null +++ b/home/shell.nix @@ -0,0 +1,203 @@ +{ 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 + 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 darwin-rebuild switch --flake ~/.config/nix#cyper-mac"; + }; + + 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; + }; +} 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/hosts/rpi-4/configuration.nix b/hosts/rpi-4/configuration.nix new file mode 100644 index 0000000..ea4fc71 --- /dev/null +++ b/hosts/rpi-4/configuration.nix @@ -0,0 +1,12 @@ +{ config, pkgs, primaryUser, ... }: + +{ + # Host-specific packages + environment.systemPackages = with pkgs; [ +# python3 +# nodejs + ]; + + # Any RPi 4 specific customizations go here + networking.hostName = "rpi-4"; +} diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..177abe0 --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,53 @@ +{ config, pkgs, inputs, self, primaryUser, ... }: + +{ + imports = [ + ./hardware.nix + ./settings.nix + ./packages.nix + ]; + + nixpkgs.config.allowUnfree = true; + + networking = { + hostName = "rpi-4"; + networkmanager.enable = true; + }; + + # SSH configuration + services.openssh = { + enable = true; + settings.PermitRootLogin = "no"; + settings.PasswordAuthentication = true; + }; + + # User configuration + users.users.${primaryUser} = { + isNormalUser = true; + home = "/home/${primaryUser}"; + description = "Phil"; + extraGroups = [ "wheel" "networkmanager" ]; + shell = pkgs.fish; + }; + + # Shell + programs.zsh.enable = true; + programs.fish.enable = true; + + # Nix settings + nix = { + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + builders = "ssh://phil@192.168.2.40 aarch64-linux"; + builders-use-substitutes = true; + }; + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 30d"; + }; + }; + + system.stateVersion = "24.11"; +} diff --git a/nixos/hardware.nix b/nixos/hardware.nix new file mode 100644 index 0000000..3dc8862 --- /dev/null +++ b/nixos/hardware.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/installer/sd-card/sd-image-aarch64.nix") + ]; + + # Bootloader + boot = { + kernelPackages = pkgs.linuxPackages_rpi4; + initrd.availableKernelModules = [ "xhci_pci" "usbhid" "usb_storage" ]; + loader.generic-extlinux-compatible.enable = true; + kernelParams = [ "console=ttyS0,115200n8" ]; + }; + + # File systems + fileSystems."/" = { + device = "/dev/disk/by-label/NIXOS_SD"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + + # Swap + swapDevices = [{ + device = "/swapfile"; + size = 4096; + }]; + + # RPi 4 specific hardware + hardware.enableRedistributableFirmware = true; + + # SD Image + image.baseName = "nixos-rpi4"; +} diff --git a/nixos/packages.nix b/nixos/packages.nix new file mode 100644 index 0000000..696ed08 --- /dev/null +++ b/nixos/packages.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + git + curl + wget + htop + neovim + tmux + ripgrep + fd + bat + eza + fzf + tree + fish + ]; +} diff --git a/nixos/settings.nix b/nixos/settings.nix new file mode 100644 index 0000000..bab9c20 --- /dev/null +++ b/nixos/settings.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + # Localization + time.timeZone = "Europe/Berlin"; + i18n.defaultLocale = "en_US.UTF-8"; + i18n.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"; + }; + + # System settings + console.keyMap = "de"; +}