diff --git a/.gitignore b/.gitignore index db72e45..78e7022 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,5 @@ result result-* -# Neovim lazy.nvim lock file +# Neovim modules/home/rsydn/programs/nvim/lazy-lock.json diff --git a/AGENTS.md b/AGENTS.md index b8dfdae..5822839 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,23 +1,19 @@ # Repository Guidelines ## Project Structure & Module Organization -This flake manages both macOS (`macbook-pro`) and NixOS (`dev-vm`) hosts. `flake.nix` collects shared modules while `flake.lock` pins inputs. Platform modules live in `modules/darwin/` and `modules/nixos/`; the Linux base `system.nix` pulls in `users.nix`, `network.nix`, `ssh.nix`, and `containerization.nix`. Host overlays such as `modules/nixos/hosts/dev-vm.nix` add virtio tooling or per-machine packages. User-facing configuration sits under `modules/home/rsydn/` with `programs/`, `shell/`, and `devtools/`; Darwin layers `shell/nushell.nix` and Linux sticks to `shell/fish.nix`. Secrets remain encrypted in `secrets/*.sops.yaml` and appear at runtime under `~/.config/secrets/`. +Shared logic lives in `flake.nix`, with inputs pinned in `flake.lock`. Platform modules sit under `modules/darwin/` and `modules/nixos/`; Linux hosts compose `modules/nixos/system.nix` plus `users.nix`, `network.nix`, `ssh.nix`, and `containerization.nix`. Host-specific overlays like `modules/nixos/hosts/dev-vm.nix` supply virtualization packages, while macOS tweaks belong in `modules/darwin/hosts/`. Home Manager layers for `rsydn` are under `modules/home/rsydn/` with `programs/`, `shell/`, and `devtools/`. Secrets stay encrypted in `secrets/*.sops.yaml` and surface at runtime in `~/.config/secrets/`. -## Build, Test & Development Commands -- `nix develop` – enter the dev shell with `git`, `nixfmt-classic`, and SOPS tooling prewired. -- `nix fmt` – format every Nix file; run before committing module or overlay changes. -- `XDG_CACHE_HOME=$PWD/.cache nix flake check` – evaluate all hosts without polluting the global cache. -- `darwin-rebuild --dry-run --flake .#macbook-pro` → `darwin-rebuild switch --flake .#macbook-pro` – preview then apply macOS updates. -- `nix build .#nixosConfigurations.dev-vm.config.system.build.toplevel` – validate the Linux VM closure before switching. +## Build, Test, and Development Commands +Use `nix develop` to enter the project shell with `git`, `nixfmt-classic`, and SOPS ready. Run `nix fmt` before committing to format all Nix sources. `XDG_CACHE_HOME=$PWD/.cache nix flake check` validates every host without polluting the global cache. For macOS changes, run `darwin-rebuild --dry-run --flake .#macbook-pro` and follow with `darwin-rebuild switch --flake .#macbook-pro`. Validate the Linux VM closure via `nix build .#nixosConfigurations.dev-vm.config.system.build.toplevel`. ## Coding Style & Naming Conventions -Use two-space indentation, trailing commas, and lower-kebab filenames (e.g. `shell/nushell.nix`). Declare custom options in the `rsydn.*` namespace and prefer shared modules over ad-hoc host tweaks. +Indent with two spaces and keep trailing commas in attribute sets. Prefer lower-kebab filenames (e.g. `shell/nushell.nix`), and expose custom options under the `rsydn.*` namespace. Format Nix with `nix fmt`; avoid ad-hoc host tweaks when a shared module fits. ## Testing Guidelines -Treat `nix flake check` as mandatory gatekeeping. Capture activation output (`darwin-rebuild --dry-run`, `nix build .#nixosConfigurations.dev-vm…`) and attach summaries to reviews. Co-locate regression tests next to their modules with the `.nix` pattern. +Treat `nix flake check` as the minimum gate; capture its output for reviews. When adjusting host builds, keep dry-run transcripts (`darwin-rebuild --dry-run`, `nix build .#nixosConfigurations.dev-vm…`) to share in PRs. Co-locate regression tests next to their modules using the `.nix` pattern. ## Commit & Pull Request Guidelines -Keep commit subjects short and imperative (`add dev-vm virtualization module`) and scope each commit narrowly. PRs should list validation commands, link issues or TODOs, and include screenshots or terminal snippets when modifying prompts, Tailscale, or SSH flows. +Write imperative commit subjects such as `add dev-vm virtualization module`, and keep each commit narrowly scoped. PRs should list validation commands run, link related issues or TODOs, and attach screenshots or terminal snippets when touching prompts, Tailscale, or SSH flows. ## Security & Configuration Tips -Age keys live at `~/.config/sops/age/keys.txt`; regenerate via Home Manager if missing. Read secrets from the managed files (`open ~/.config/secrets/openai-api-key | str trim`) and scope them with `with-env`. Tailscale and OpenSSH run by default on Linux; rotate keys regularly and audit `services.tailscale.extraUpFlags` before enabling exit nodes. +Age keys live at `~/.config/sops/age/keys.txt`; regenerate via Home Manager if missing. Access secrets with `open ~/.config/secrets/ | str trim` and scope them using `with-env`. Audit `services.tailscale.extraUpFlags` before enabling exit nodes, and rotate SSH/Tailscale keys regularly. diff --git a/README.MD b/README.MD index ee1c145..8a7f0da 100644 --- a/README.MD +++ b/README.MD @@ -7,7 +7,7 @@ So far, the dotfiles only used for my macOS configuration, maybe in the future I ## Core System - OS: macOS (nix-darwin) -- Shell: nushell with oh-my-posh +- Shell: nushell with starship prompt - Terminal: ghostty with dracula theme - Package Management: mix of nix and homebrew diff --git a/devshells/README.md b/devshells/README.md index 5e5872b..9660bdb 100644 --- a/devshells/README.md +++ b/devshells/README.md @@ -34,37 +34,35 @@ nix develop .#python-uv - Ruff (linter/formatter) - Pyright (type checker) -### `ml-ai` -Machine Learning and AI development with HuggingFace model management. +### `ai-notebook` +Notebook-focused ML/AI environment with HuggingFace tooling and JupyterLab. ```bash -nix develop .#ml-ai +nix develop .#ai-notebook ``` **Includes:** -- Python 3.12 with huggingface-hub -- `huggingface-cli` for downloading models -- UV for package management -- Git LFS for large files -- Ruff and Pyright +- Python 3.12 with JupyterLab, NumPy/Pandas/SciPy stack +- HuggingFace `transformers`, `datasets`, `accelerate`, `tokenizers` +- Vision tooling: OpenCV, scikit-image, Pillow, albumentations, Altair/Plotly +- Optional CPU PyTorch (Linux hosts) plus torchvision/torchaudio +- UV, Ruff, Pyright, Git LFS -**Model cache:** `~/.cache/huggingface` (persistent across projects) +**HuggingFace caches:** +- Models: `~/.cache/huggingface/hub` +- Transformers: `~/.cache/huggingface/transformers` **Example usage:** ```bash -# Download a TTS model -huggingface-cli download facebook/mms-tts-eng +# Launch JupyterLab with AI helpers +jupyter lab -# Download a small LLM +# Download a model or dataset huggingface-cli download meta-llama/Llama-3.2-1B +python -c "from datasets import load_dataset; load_dataset('ag_news')" -# Download specific files only -huggingface-cli download openai/whisper-large-v3 --include "*.json" "*.safetensors" - -# Use in your project -uv init my-ml-project -cd my-ml-project -uv add transformers torch +# Fine-tune with Accelerate +python -m accelerate.commands.launch train.py ``` ### `go` @@ -107,13 +105,6 @@ nix develop .#rust - rustfmt - clippy -### `zig-nightly` (optional) -Zig nightly development (only available if zig overlay is working). - -```bash -nix develop .#zig-nightly -``` - ## Usage from Any Directory ### Option 1: Direct Path Reference @@ -121,7 +112,7 @@ Use the full path to your dotfiles: ```bash cd ~/my-project -nix develop ~/Development/dotfiles#ml-ai +nix develop ~/Development/dotfiles#ai-notebook ``` ### Option 2: Flake Registry Alias (Recommended) @@ -137,7 +128,7 @@ nix registry list | grep dotfiles **Then from anywhere:** ```bash cd ~/any-project -nix develop dotfiles#ml-ai +nix develop dotfiles#ai-notebook ``` Benefits: Shorter commands, cleaner paths, easy to remember! @@ -152,14 +143,14 @@ nix registry add dotfiles ~/Development/dotfiles # In each project: cd ~/my-ml-project -echo "use flake dotfiles#ml-ai" > .envrc +echo "use flake dotfiles#ai-notebook" > .envrc direnv allow ``` **Alternative: Without registry (using full path):** ```bash cd ~/my-ml-project -echo "use flake ~/Development/dotfiles#ml-ai" > .envrc +echo "use flake ~/Development/dotfiles#ai-notebook" > .envrc direnv allow ``` @@ -179,7 +170,7 @@ Create a `flake.nix` in your project that imports the shell: let system = "aarch64-darwin"; in { - devShells.${system}.default = dotfiles.devShells.${system}.ml-ai; + devShells.${system}.default = dotfiles.devShells.${system}.ai-notebook; }; } ``` @@ -194,9 +185,9 @@ nix develop | Method | Command | Pros | |--------|---------|------| -| Direct path | `nix develop ~/Development/dotfiles#ml-ai` | Simple, no setup | -| Registry | `nix develop dotfiles#ml-ai` | Clean, short commands | -| direnv + registry | `echo "use flake dotfiles#ml-ai" > .envrc` | Auto-loads, clean | +| Direct path | `nix develop ~/Development/dotfiles#ai-notebook` | Simple, no setup | +| Registry | `nix develop dotfiles#ai-notebook` | Clean, short commands | +| direnv + registry | `echo "use flake dotfiles#ai-notebook" > .envrc` | Auto-loads, clean | | Project flake | `nix develop` | Shareable, version-controlled | ## Adding New Shells diff --git a/devshells/ai-notebook.nix b/devshells/ai-notebook.nix new file mode 100644 index 0000000..5da154c --- /dev/null +++ b/devshells/ai-notebook.nix @@ -0,0 +1,54 @@ +{ pkgs, lib, python ? pkgs.python312, ... }: + +let + pythonWithAI = python.withPackages (ps: + let + basePackages = with ps; [ + accelerate + albumentations + altair + datasets + evaluate + huggingface-hub + ipykernel + jupyterlab + matplotlib + numpy + opencv4 + pandas + pillow + plotly + scipy + scikit-image + scikit-learn + seaborn + sentencepiece + tokenizers + transformers + ]; + linuxOnlyPackages = lib.optionals pkgs.stdenv.isLinux + (with ps; [ torch torchaudio torchvision ]); + in basePackages ++ linuxOnlyPackages); +in pkgs.mkShell { + name = "ai-notebook"; + packages = with pkgs; [ pythonWithAI uv git-lfs ruff pyright ]; + + shellHook = '' + export UV_PYTHON="${pythonWithAI}/bin/python3" + export UV_LINK_MODE=copy + + export PYTHONNOUSERSITE=1 + export HF_HOME="''${XDG_CACHE_HOME:-$HOME/.cache}/huggingface" + export HF_HUB_CACHE="$HF_HOME/hub" + export TRANSFORMERS_CACHE="$HF_HOME/transformers" + export JUPYTER_CONFIG_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/jupyter" + + mkdir -p "$HF_HOME" "$JUPYTER_CONFIG_DIR" + + echo "AI notebook shell ready" + echo "Python: ${python.version}" + echo "HuggingFace cache: $HF_HOME" + echo "Launch JupyterLab: jupyter lab" + echo "Launch classic notebook: jupyter notebook" + ''; +} diff --git a/devshells/default.nix b/devshells/default.nix index c0c3b43..47cdfc5 100644 --- a/devshells/default.nix +++ b/devshells/default.nix @@ -35,15 +35,65 @@ let echo "Restart Claude Code and Codex to apply changes." ''; + # Helper that builds the wrapped Neovim from the flake and runs it with repo-scoped XDG dirs + previewNvim = pkgs.writeShellScriptBin "preview-nvim" '' + set -euo pipefail + + root="''${DOTFILES_ROOT:-$PWD}" + cache_base="$root/.cache" + nvim_cache="$cache_base/nvim-preview" + xdg_state="$cache_base/xdg-state" + xdg_data="$cache_base/xdg-data" + xdg_config="$root/modules/home/rsydn/programs" + + mkdir -p "$nvim_cache" "$xdg_state" "$xdg_data" + + attr="''${NVIM_ATTR:-}" + if [ "$#" -gt 0 ]; then + attr="$1" + shift + fi + + if [ -z "$attr" ]; then + case "$(uname -s)" in + Darwin) + attr=".#darwinConfigurations.macbook-pro.config.home-manager.users.rasyidanakbar.programs.neovim.finalPackage" + ;; + Linux) + attr=".#nixosConfigurations.dev-vm.config.home-manager.users.rasyidanakbar.programs.neovim.finalPackage" + ;; + *) + echo "error: unsupported system; pass flake attribute as first argument or set NVIM_ATTR" >&2 + exit 1 + ;; + esac + fi + + out_link="$nvim_cache/result" + + echo "Building Neovim package: $attr" + XDG_CACHE_HOME="$nvim_cache" nix build "$attr" --out-link "$out_link" + + echo "Launching Neovim..." + XDG_CACHE_HOME="$nvim_cache" \ + XDG_STATE_HOME="$xdg_state" \ + XDG_DATA_HOME="$xdg_data" \ + XDG_CONFIG_HOME="$xdg_config" \ + NVIM_APPNAME="nvim" \ + "$out_link/bin/nvim" "$@" + ''; + in pkgs.mkShell { name = "default"; packages = with pkgs; [ git + nix nixfmt-classic uv python3 mcpNixosWrapper installMcpConfigs + previewNvim ]; shellHook = '' export DOTFILES_ROOT="$PWD" @@ -63,5 +113,8 @@ in pkgs.mkShell { echo "" echo "To install MCP configs for Claude Code and Codex, run:" echo " install-mcp-configs" + echo "" + echo "To preview the Neovim config without switching, run:" + echo " preview-nvim [flakeAttr] [-- extra args]" ''; } diff --git a/devshells/jupyter-notebook.nix b/devshells/jupyter-notebook.nix new file mode 100644 index 0000000..f8db924 --- /dev/null +++ b/devshells/jupyter-notebook.nix @@ -0,0 +1,31 @@ +{ pkgs, python ? pkgs.python312, ... }: + +let + # Python environment with notebook tooling and core data-science libs + pythonWithNotebook = python.withPackages (ps: + with ps; [ + altair + ipykernel + jupyterlab + matplotlib + numpy + pandas + polars + plotly + scipy + scikit-learn + seaborn + ]); +in pkgs.mkShell { + name = "jupyter-notebook"; + packages = [ pythonWithNotebook pkgs.ruff pkgs.pyright pkgs.git ]; + shellHook = '' + export PYTHONNOUSERSITE=1 + export JUPYTER_CONFIG_DIR="''${XDG_CONFIG_HOME:-$HOME/.config}/jupyter" + mkdir -p "$JUPYTER_CONFIG_DIR" + echo "Jupyter notebook shell ready" + echo "Python: ${python.version}" + echo "Launch notebook: jupyter lab" + echo "Launch classic: jupyter notebook" + ''; +} diff --git a/devshells/ml-ai.nix b/devshells/ml-ai.nix deleted file mode 100644 index 4e31ebd..0000000 --- a/devshells/ml-ai.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ pkgs, python ? pkgs.python312, ... }: - -let - # Create a Python environment with huggingface-cli - pythonWithHF = python.withPackages (ps: [ ps.huggingface-hub ]); -in pkgs.mkShell { - name = "ml-ai"; - packages = with pkgs; [ pythonWithHF uv git-lfs ruff pyright ]; - shellHook = '' - # Set up UV - export UV_PYTHON="${pythonWithHF}/bin/python3" - export UV_LINK_MODE=copy - - # Set up HuggingFace cache (persistent across projects) - export HF_HOME="''${XDG_CACHE_HOME:-$HOME/.cache}/huggingface" - export HF_HUB_CACHE="$HF_HOME/hub" - mkdir -p "$HF_HOME" - - # Optional: Set offline mode (uncomment to use only cached models) - # export HF_HUB_OFFLINE=1 - - echo "ML/AI shell ready" - echo "Python: ${python.version}" - echo "HuggingFace cache: $HF_HOME" - echo "" - echo "Download models with:" - echo " huggingface-cli download " - echo "" - echo "Example TTS:" - echo " huggingface-cli download facebook/mms-tts-eng" - echo "" - echo "Example LLM:" - echo " huggingface-cli download meta-llama/Llama-3.2-1B" - ''; -} diff --git a/devshells/zig-nightly.nix b/devshells/zig-nightly.nix deleted file mode 100644 index 2d7b5be..0000000 --- a/devshells/zig-nightly.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ pkgs, lib, zigPackage, ... }: - -lib.optionalAttrs (zigPackage != null) (pkgs.mkShell { - name = "zig-nightly"; - packages = [ zigPackage pkgs.zls pkgs.pkg-config pkgs.cmake pkgs.gdb ]; - shellHook = '' - mkdir -p "$PWD/.cache/zig" - export ZIG_GLOBAL_CACHE_DIR="$PWD/.cache/zig" - echo "Zig shell using ${zigPackage.pname or "zig"} ${ - zigPackage.version or "" - }" - ''; -}) diff --git a/flake.lock b/flake.lock index 53c026c..effa4b3 100644 --- a/flake.lock +++ b/flake.lock @@ -22,6 +22,29 @@ "type": "github" } }, + "chaotic": { + "inputs": { + "flake-schemas": "flake-schemas", + "home-manager": "home-manager", + "jovian": "jovian", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1761265276, + "narHash": "sha256-ZngDL68RZbT1RUX/m+h8y5zfXJdnydRKjf3oZTfwam0=", + "owner": "chaotic-cx", + "repo": "nyx", + "rev": "5df2883e9401fd257e39285819996203628f3f0e", + "type": "github" + }, + "original": { + "owner": "chaotic-cx", + "ref": "nyxpkgs-unstable", + "repo": "nyx", + "type": "github" + } + }, "darwin": { "inputs": { "nixpkgs": [ @@ -58,20 +81,18 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, + "flake-schemas": { "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" + "lastModified": 1721999734, + "narHash": "sha256-G5CxYeJVm4lcEtaO87LKzOsVnWeTcHGKbKxNamNWgOw=", + "rev": "0a5c42297d870156d9c57d8f99e476b738dcd982", + "revCount": 75, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.1.5/0190ef2f-61e0-794b-ba14-e82f225e55e6/source.tar.gz" }, "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" + "type": "tarball", + "url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%3D0.1.5.tar.gz" } }, "flake-utils": { @@ -92,24 +113,6 @@ "type": "github" } }, - "flake-utils_2": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1705309234, - "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, "ghostty": { "inputs": { "flake-compat": "flake-compat", @@ -137,6 +140,7 @@ "home-manager": { "inputs": { "nixpkgs": [ + "chaotic", "nixpkgs" ] }, @@ -154,6 +158,48 @@ "type": "github" } }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1761081701, + "narHash": "sha256-IwpfaKg5c/WWQiy8b5QGaVPMvoEQ2J6kpwRFdpVpBNQ=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "9b4a2a7c4fbd75b422f00794af02d6edb4d9d315", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "jovian": { + "inputs": { + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "chaotic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1761045626, + "narHash": "sha256-N0OyyLp7VIYUdrtLSPt6y40q3+wAAeJWRwAtrKtHYtU=", + "owner": "Jovian-Experiments", + "repo": "Jovian-NixOS", + "rev": "493f3428943605a9a34494cfcba32cd21633752f", + "type": "github" + }, + "original": { + "owner": "Jovian-Experiments", + "repo": "Jovian-NixOS", + "type": "github" + } + }, "nix-ai-tools": { "inputs": { "blueprint": "blueprint", @@ -163,11 +209,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1761103959, - "narHash": "sha256-TSle1gTii9QSLZIaGdpts0G+9E+vCHksnS5nsreyf1c=", + "lastModified": 1761533636, + "narHash": "sha256-4xLNB3dIObQIA8m5WFR/ikssWddGc9l5QsyQNaLuoeU=", "owner": "numtide", "repo": "nix-ai-tools", - "rev": "2191428a02fc107acbbadd796bf80076a7baa770", + "rev": "07559be9aee853a3a5968f2fcda14c07477a132d", "type": "github" }, "original": { @@ -176,7 +222,46 @@ "type": "github" } }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "chaotic", + "jovian", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1729697500, + "narHash": "sha256-VFTWrbzDlZyFHHb1AlKRiD/qqCJIripXKiCSFS8fAOY=", + "owner": "zhaofengli", + "repo": "nix-github-actions", + "rev": "e418aeb728b6aa5ca8c5c71974e7159c2df1d8cf", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "ref": "matrix-name", + "repo": "nix-github-actions", + "type": "github" + } + }, "nixpkgs": { + "locked": { + "lastModified": 1761114652, + "narHash": "sha256-f/QCJM/YhrV/lavyCVz8iU3rlZun6d+dAiC3H+CDle4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "01f116e4df6a15f4ccdffb1bcd41096869fb385c", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1758360447, "narHash": "sha256-XDY3A83bclygHDtesRoaRTafUd80Q30D/Daf9KSG6bs=", @@ -189,13 +274,13 @@ "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" } }, - "nixpkgs_2": { + "nixpkgs_3": { "locked": { - "lastModified": 1760878510, - "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=", + "lastModified": 1761373498, + "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67", + "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", "type": "github" }, "original": { @@ -207,13 +292,34 @@ }, "root": { "inputs": { + "chaotic": "chaotic", "darwin": "darwin", "ghostty": "ghostty", - "home-manager": "home-manager", + "home-manager": "home-manager_2", "nix-ai-tools": "nix-ai-tools", - "nixpkgs": "nixpkgs_2", - "sops-nix": "sops-nix", - "zig-overlay": "zig-overlay" + "nixpkgs": "nixpkgs_3", + "sops-nix": "sops-nix" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "chaotic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1761100675, + "narHash": "sha256-LX3TCDBeNpCWTDXtGyRASVcLmRPChSli34bgHnZ1DCw=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "72161c6c53f6e3f8dadaf54b2204a5094c6a16ae", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" } }, "sops-nix": { @@ -266,21 +372,6 @@ "type": "github" } }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, "treefmt-nix": { "inputs": { "nixpkgs": [ @@ -289,11 +380,11 @@ ] }, "locked": { - "lastModified": 1760945191, - "narHash": "sha256-ZRVs8UqikBa4Ki3X4KCnMBtBW0ux1DaT35tgsnB1jM4=", + "lastModified": 1761311587, + "narHash": "sha256-Msq86cR5SjozQGCnC6H8C+0cD4rnx91BPltZ9KK613Y=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "f56b1934f5f8fcab8deb5d38d42fd692632b47c2", + "rev": "2eddae033e4e74bf581c2d1dfa101f9033dbd2dc", "type": "github" }, "original": { @@ -331,31 +422,9 @@ "type": "github" } }, - "zig-overlay": { - "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": "flake-utils_2", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1760747435, - "narHash": "sha256-wNB/W3x+or4mdNxFPNOH5/WFckNpKgFRZk7OnOsLtm0=", - "owner": "mitchellh", - "repo": "zig-overlay", - "rev": "d0f239b887b1ac736c0f3dde91bf5bf2ecf3a420", - "type": "github" - }, - "original": { - "owner": "mitchellh", - "repo": "zig-overlay", - "type": "github" - } - }, "zon2nix": { "inputs": { - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1758405547, diff --git a/flake.nix b/flake.nix index 3c84956..a4ad5e5 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,11 @@ sops-nix.url = "github:Mic92/sops-nix"; sops-nix.inputs.nixpkgs.follows = "nixpkgs"; - zig-overlay.url = "github:mitchellh/zig-overlay"; - zig-overlay.inputs.nixpkgs.follows = "nixpkgs"; + chaotic.url = "github:chaotic-cx/nyx/nyxpkgs-unstable"; }; outputs = inputs@{ self, nixpkgs, darwin, home-manager, ghostty, nix-ai-tools - , sops-nix, ... }: + , sops-nix, chaotic, ... }: let inherit (nixpkgs.lib) genAttrs; lib = nixpkgs.lib; @@ -34,12 +33,7 @@ forEachSystem = f: genAttrs systems (system: f system); - overlaysList = [ ghostty.overlays.default ]; - - zigOverlay = if builtins.hasAttr "zig-overlay" inputs then - inputs."zig-overlay" - else - null; + overlaysList = [ ghostty.overlays.default chaotic.overlays.default ]; mkPkgs = system: import nixpkgs { @@ -49,12 +43,13 @@ }; sharedDarwinModules = [ ./modules/darwin/system.nix ]; - sharedNixosModules = [ ./modules/nixos/system.nix ]; + sharedNixosModules = + [ ./modules/nixos/system.nix chaotic.nixosModules.default ]; user = "rasyidanakbar"; mkDarwin = { system ? "aarch64-darwin", extraModules ? [ ] - , homeFile ? ./modules/darwin/home/default.nix }: + , homeFile ? ./modules/darwin/home/default.nix, }: let pkgs = mkPkgs system; in darwin.lib.darwinSystem { inherit system pkgs; @@ -74,7 +69,7 @@ ]; }; mkNixos = { system ? "x86_64-linux", extraModules ? [ ] - , homeFile ? ./modules/nixos/home/default.nix }: + , homeFile ? ./modules/nixos/home/default.nix, }: let pkgs = mkPkgs system; in lib.nixosSystem { inherit system pkgs; @@ -98,6 +93,14 @@ dev-vm = mkNixos { system = "x86_64-linux"; extraModules = [ ./modules/nixos/hosts/dev-vm.nix ]; + # Uses default homeFile: ./modules/nixos/home/default.nix + }; + desktop = mkNixos { + system = "x86_64-linux"; + extraModules = [ ./modules/nixos/hosts/desktop.nix ]; + # Home Manager configs are imported directly in desktop modules + # No homeFile needed - using inline home-manager.users.${user} + homeFile = ./modules/nixos/home/default.nix; }; }; @@ -109,49 +112,8 @@ else pkgs.python3; - # Zig overlay setup for zig-nightly shell - zigPackages = - if zigOverlay != null && builtins.hasAttr "packages" zigOverlay then - zigOverlay.packages - else - { }; - - zigCandidate = - if zigOverlay != null && system == "aarch64-darwin" then - lib.attrByPath [ system "master" "zig" ] null zigPackages - else - null; - - zigCandidateBroken = if zigCandidate != null then - if zigCandidate ? meta && zigCandidate.meta ? broken then - zigCandidate.meta.broken - else - false - else - true; - - zigFallback = pkgs.zig; - zigFallbackBroken = - if zigFallback ? meta && zigFallback.meta ? broken then - zigFallback.meta.broken - else - false; - - zigPackage = - if zigCandidate != null && zigCandidateBroken == false then - zigCandidate - else if zigFallbackBroken == false then - zigFallback - else - null; - - zlsBroken = if pkgs.zls ? meta && pkgs.zls.meta ? broken then - pkgs.zls.meta.broken - else - false; - # Common arguments passed to all devshell imports - shellArgs = { inherit pkgs lib python zigPackage; }; + shellArgs = { inherit pkgs lib python; }; # Import all devshells from devshells/ directory importShell = name: import (./devshells + "/${name}.nix") shellArgs; @@ -159,12 +121,11 @@ in { default = importShell "default"; python-uv = importShell "python-uv"; - ml-ai = importShell "ml-ai"; + ai-notebook = importShell "ai-notebook"; + jupyter-notebook = importShell "jupyter-notebook"; go = importShell "go"; web-bun = importShell "web-bun"; rust = importShell "rust"; - } // lib.optionalAttrs (zigPackage != null && zlsBroken == false) { - zig-nightly = importShell "zig-nightly"; }); formatter = forEachSystem (system: (mkPkgs system).nixfmt-classic); diff --git a/modules/darwin/home/default.nix b/modules/darwin/home/default.nix index d227980..a8d3ab9 100644 --- a/modules/darwin/home/default.nix +++ b/modules/darwin/home/default.nix @@ -6,4 +6,56 @@ ./programs/aerospace ./programs/ghostty.nix ]; + + # Darwin-specific secrets configuration + rsydn.secrets = { + enable = lib.mkDefault true; + defaultSopsFile = ../../../secrets/local-ai-tokens.sops.yaml; + secrets = { + "openai-api-key" = { + format = "yaml"; + key = "OPENAI_API_KEY"; + }; + + "openrouter-api-key" = { + format = "yaml"; + key = "OPENROUTER_API_KEY"; + }; + + "zai-api-key" = { + format = "yaml"; + key = "ZAI_API_KEY"; + }; + + "moonshot-api-key" = { + format = "yaml"; + key = "MOONSHOT_API_KEY"; + }; + + "anthropic-api-key" = { + format = "yaml"; + key = "ANTHROPIC_API_KEY"; + }; + + "exa-api-key" = { + format = "yaml"; + key = "EXA_API_KEY"; + }; + + "fal-api-key" = { + format = "yaml"; + key = "FAL_API_KEY"; + }; + + "groq-api-key" = { + format = "yaml"; + key = "GROQ_API_KEY"; + }; + + "firecrawl-api-key" = { + format = "yaml"; + key = "FIRECRAWL_API_KEY"; + }; + }; + }; } diff --git a/modules/darwin/homebrew.nix b/modules/darwin/homebrew.nix index 50e869f..b6637b4 100644 --- a/modules/darwin/homebrew.nix +++ b/modules/darwin/homebrew.nix @@ -16,35 +16,22 @@ in { }; brews = mkOption { type = types.listOf types.str; - default = [ - "curl" - "yt-dlp" - "ruff" - "libmagic" - "ghostscript" - "infisical" - "fastfetch" - "neofetch" - ]; + default = [ "curl" "yt-dlp" "ruff" "libmagic" "infisical" ]; description = "Homebrew formulae to install."; }; casks = mkOption { type = types.listOf types.str; default = [ "bitwarden" - "chromium" - "dbngin" + "brave-browser" + "firefox" "pgadmin4" "docker-desktop" - "iterm2" "spotify" - "discord" + "vesktop" "obs" "neohtop" "orbstack" - "visual-studio-code" - "google-chrome@canary" - "mactex" "ghostty" ]; description = "Homebrew casks to install."; diff --git a/modules/darwin/system.nix b/modules/darwin/system.nix index 82898d4..8a92b20 100644 --- a/modules/darwin/system.nix +++ b/modules/darwin/system.nix @@ -23,11 +23,20 @@ }; }; - environment.shells = [ pkgs.nushell ]; + environment.shells = [ pkgs.nushell "/etc/profiles/per-user/${user}/bin/nu" ]; + + # Set XDG Base Directory environment variables globally + # This ensures nushell and other XDG-compliant tools use ~/.config + environment.variables = { + XDG_CONFIG_HOME = "$HOME/.config"; + XDG_DATA_HOME = "$HOME/.local/share"; + XDG_CACHE_HOME = "$HOME/.cache"; + }; users.users.${user} = { home = lib.mkDefault "/Users/${user}"; - shell = pkgs.nushell; + # Use the Home Manager nushell which has proper config setup + shell = "/etc/profiles/per-user/${user}/bin/nu"; }; system = { diff --git a/modules/home/rsydn/base.nix b/modules/home/rsydn/base.nix index e29175f..8627723 100644 --- a/modules/home/rsydn/base.nix +++ b/modules/home/rsydn/base.nix @@ -1,111 +1,69 @@ { pkgs, lib, ... }: { - home.stateVersion = "24.05"; - imports = [ + ./programs/fastfetch.nix ./programs/helix.nix ./programs/neovim.nix ./shell/tmux.nix + ./shell/starship ./devtools/ai-tools.nix ./devtools/languages.nix ./devtools/default.nix ./secrets.nix ]; - programs.git.enable = true; + config = { + home.stateVersion = "24.05"; - home.packages = with pkgs; [ docker docker-compose ]; + # XDG Base Directory specification + # Ensures ~/.config, ~/.local/share, ~/.cache are properly set up + # Note: User directories (Desktop, Downloads, etc.) are configured in desktop modules + xdg.enable = true; - rsydn.aiTools = { - enable = lib.mkDefault true; - claude.zai.enable = lib.mkDefault true; - }; + programs.git.enable = true; - rsydn.devTools = { - enable = lib.mkDefault true; - packages = with pkgs; [ - ast-grep - cloudflared - ffmpeg - fzf - htop - jetbrains-mono - jq - jujutsu - lazydocker - lazygit - lorri - nil - nixd - pandoc - ripgrep - tmux - tree - curl - vim - wget - yq - ]; - }; + home.packages = with pkgs; [ docker docker-compose ]; - rsydn.languages = { - enable = lib.mkDefault true; - # Disable global language tools - use nix develop shells instead - cargo.enable = false; - go.enable = false; - bun.enable = false; - # Keep uv for MCP server and node for npx/tooling - uv.enable = true; - node.enable = true; - }; + rsydn.aiTools = { + enable = lib.mkDefault true; + claude.zai.enable = lib.mkDefault true; + }; - rsydn.secrets = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { - enable = lib.mkDefault true; - defaultSopsFile = ../../../secrets/local-ai-tokens.sops.yaml; - secrets = { - "openai-api-key" = { - format = "yaml"; - key = "OPENAI_API_KEY"; - }; + rsydn.devTools = { + enable = lib.mkDefault true; + packages = with pkgs; [ + ast-grep + cloudflared + ffmpeg + fzf + htop + jetbrains-mono + jq + jujutsu + lazydocker + lazygit + lorri + nil + nixd + pandoc + ripgrep + tmux + tree + curl + vim + wget + yq + ]; + }; - "openrouter-api-key" = { - format = "yaml"; - key = "OPENROUTER_API_KEY"; - }; - - "zai-api-key" = { - format = "yaml"; - key = "ZAI_API_KEY"; - }; - - "moonshot-api-key" = { - format = "yaml"; - key = "MOONSHOT_API_KEY"; - }; - - "anthropic-api-key" = { - format = "yaml"; - key = "ANTHROPIC_API_KEY"; - }; - - "exa-api-key" = { - format = "yaml"; - key = "EXA_API_KEY"; - }; - - "fal-api-key" = { - format = "yaml"; - key = "FAL_API_KEY"; - }; - - "groq-api-key" = { - format = "yaml"; - key = "GROQ_API_KEY"; - }; - - "firecrawl-api-key" = { - format = "yaml"; - key = "FIRECRAWL_API_KEY"; - }; + rsydn.languages = { + enable = lib.mkDefault true; + # Disable global language tools - use nix develop shells instead + cargo.enable = false; + go.enable = false; + bun.enable = false; + # Keep uv for MCP server and node for npx/tooling + uv.enable = true; + node.enable = true; }; }; } diff --git a/modules/home/rsydn/programs/fastfetch.nix b/modules/home/rsydn/programs/fastfetch.nix new file mode 100644 index 0000000..f3ccd69 --- /dev/null +++ b/modules/home/rsydn/programs/fastfetch.nix @@ -0,0 +1,156 @@ +{ config, lib, pkgs, ... }: + +{ + home.packages = [ pkgs.fastfetch ]; + + # Copy the custom logo file + xdg.configFile."fastfetch/oguri-logo.txt".source = ./fastfetch/oguri-logo.txt; + + xdg.configFile."fastfetch/config.jsonc".text = + let esc = builtins.fromJSON ''"\u001b"''; + in builtins.toJSON { + "$schema" = + "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json"; + + logo = { + type = "file"; + source = "~/.config/fastfetch/oguri-logo.txt"; + color."1" = "green"; + padding = { + top = 2; + right = 6; + left = 2; + }; + }; + + display = { + separator = " → "; + key = { width = 16; }; + }; + + modules = [ + "break" + + # Hardware Section + { + type = "custom"; + format = + "${esc}[32m── Hardware──────────────────────────────────────────${esc}[0m"; + } + { + type = "host"; + key = " PC"; + keyColor = "green"; + } + { + type = "cpu"; + key = " CPU"; + showPeCoreCount = true; + keyColor = "green"; + } + { + type = "gpu"; + key = " GPU"; + detectionMethod = "pci"; + keyColor = "green"; + } + { + type = "display"; + key = "󱄄 Display"; + keyColor = "green"; + } + { + type = "disk"; + key = "󰋊 Disk"; + keyColor = "green"; + } + { + type = "memory"; + key = " Memory"; + keyColor = "green"; + } + { + type = "swap"; + key = "󰓡 Swap"; + keyColor = "green"; + } + "break" + + # Software Section + { + type = "custom"; + format = + "${esc}[34m── Software──────────────────────────────────────────${esc}[0m"; + } + { + type = "command"; + key = "ue900 OS"; + keyColor = "blue"; + text = ''version=$(omarchy-version); echo "Omarchy $version"''; + } + { + type = "command"; + key = "󰘬 Branch"; + keyColor = "blue"; + text = ''branch=$(omarchy-version-branch); echo "$branch"''; + } + { + type = "kernel"; + key = " Kernel"; + keyColor = "blue"; + } + { + type = "wm"; + key = " WM"; + keyColor = "blue"; + } + { + type = "de"; + key = " DE"; + keyColor = "blue"; + } + { + type = "terminal"; + key = " Terminal"; + keyColor = "blue"; + } + { + type = "packages"; + key = "󰏖 Packages"; + keyColor = "blue"; + } + { + type = "wmtheme"; + key = "󰉼 WM Theme"; + keyColor = "blue"; + } + { + type = "terminalfont"; + key = " Terminal Font"; + keyColor = "blue"; + } + "break" + + # Uptime / Age Section + { + type = "custom"; + format = + "${esc}[35m── Uptime / Age─────────────────────────────────────${esc}[0m"; + } + { + type = "command"; + key = "󱦟 OS Age"; + keyColor = "magenta"; + # macOS compatible stat command + text = '' + if [ $(uname) = 'Darwin' ]; then birth=$(stat -f %B /); else birth=$(stat -c %W /); fi; current=$(date +%s); days=$(( (current - birth) / 86400 )); echo "$days days"''; + } + { + type = "uptime"; + key = "󱫐 Uptime"; + keyColor = "magenta"; + } + "break" + ]; + }; +} diff --git a/modules/home/rsydn/programs/fastfetch/oguri-logo.txt b/modules/home/rsydn/programs/fastfetch/oguri-logo.txt new file mode 100644 index 0000000..d49bea4 --- /dev/null +++ b/modules/home/rsydn/programs/fastfetch/oguri-logo.txt @@ -0,0 +1,18 @@ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣽⣶⣿⣏⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣼⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣫ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⡿⣹⣿⡇⢸⣿⢿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⡿⣁⣇⣿⠀⠈⡟⠘⣿⣿⡇⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣟⢀⠿⡏⣽⣴⣦⣿⠀⣹⣿⡇⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣷⣶⣿⣿⣿⣿⣧⣿⣿⣷⣀⡀⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣸⣿⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣿⣿⣿⣿⣿⣷⣞⣿⣿⣿⣿⣿⡿⣹⠏⠀⣿⠃⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣿⣿⣿⣯⢀⣇⣀⡸⠁⢸⠏⢿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣏⡉⠻⣿⣿⡇⢠⣿⣄⢸⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⣸⣿⣿⣿⣿⣿⣦⣭⣑⢛⠋⠁⢸⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢯⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢿⣿⣿⣿⣿ +⣿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠋⢠⣿⣿⣿⣿⣿ +⣿⣷⣿⣿⡿⠿⠿⠟⠛⣻⣿⣿⣿⣿⣿⣿⣿⡿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⣠⣿⣿⣿⣟⣿⣿ +⣿⣏⠁⢀⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⠈⠁⠉⠛⢿⣿⣿⣿⣴⣿⣿⠿⢋⡾⢡⣿ diff --git a/modules/home/rsydn/programs/neovim.nix b/modules/home/rsydn/programs/neovim.nix index 29e67e8..fecf477 100644 --- a/modules/home/rsydn/programs/neovim.nix +++ b/modules/home/rsydn/programs/neovim.nix @@ -9,20 +9,48 @@ withPython3 = true; withRuby = true; + plugins = with pkgs.vimPlugins; [ + # Native extensions that need building + telescope-fzf-native-nvim + blink-cmp # Pre-built with Rust backend for fast fuzzy matching + ]; + extraPackages = with pkgs; [ - # LSP servers + # LSP Servers lua-language-server - nil + nil # Nix LSP + pyright + nodePackages.typescript-language-server + rust-analyzer + gopls + clang-tools # provides clangd # Formatters - stylua - nixfmt + stylua # Lua + nixfmt-classic # Nix (matches your fmt command) + ruff # Python (formatter + linter) + prettierd # JS/TS/JSON/YAML/Markdown + rustfmt # Rust + gofumpt # Go (stricter than gofmt) + shfmt # Shell scripts + + # Linters + nodePackages.eslint # JavaScript/TypeScript + shellcheck # Shell scripts # Tools ripgrep fd git ast-grep + + # Additional tools for LazyVim features + tree-sitter # Required for treesitter parser compilation + imagemagick # Image conversion for snacks.nvim + ghostscript # PDF rendering support + tectonic # LaTeX math rendering + luarocks # Lua package manager for plugins + nodePackages.mermaid-cli # Mermaid diagram rendering ]; }; diff --git a/modules/home/rsydn/programs/nvim/.gitignore b/modules/home/rsydn/programs/nvim/.gitignore deleted file mode 100644 index cc5457a..0000000 --- a/modules/home/rsydn/programs/nvim/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -tt.* -.tests -doc/tags -debug -.repro -foo.* -*.log -data diff --git a/modules/home/rsydn/programs/nvim/.luarc.json b/modules/home/rsydn/programs/nvim/.luarc.json new file mode 100644 index 0000000..99875e2 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/.luarc.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", + "runtime": { + "version": "LuaJIT", + "path": [ + "lua/?.lua", + "lua/?/init.lua" + ] + }, + "diagnostics": { + "globals": ["vim"] + }, + "workspace": { + "library": [ + "${3rd}/luv/library", + "${3rd}/busted/library", + "${3rd}/luassert/library" + ], + "checkThirdParty": false + }, + "completion": { + "callSnippet": "Replace" + }, + "telemetry": { + "enable": false + } +} diff --git a/modules/home/rsydn/programs/nvim/.neoconf.json b/modules/home/rsydn/programs/nvim/.neoconf.json deleted file mode 100644 index 7c48087..0000000 --- a/modules/home/rsydn/programs/nvim/.neoconf.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "neodev": { - "library": { - "enabled": true, - "plugins": true - } - }, - "neoconf": { - "plugins": { - "lua_ls": { - "enabled": true - } - } - } -} diff --git a/modules/home/rsydn/programs/nvim/LICENSE b/modules/home/rsydn/programs/nvim/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/modules/home/rsydn/programs/nvim/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/modules/home/rsydn/programs/nvim/README.md b/modules/home/rsydn/programs/nvim/README.md deleted file mode 100644 index 185280b..0000000 --- a/modules/home/rsydn/programs/nvim/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# 💤 LazyVim - -A starter template for [LazyVim](https://github.com/LazyVim/LazyVim). -Refer to the [documentation](https://lazyvim.github.io/installation) to get started. diff --git a/modules/home/rsydn/programs/nvim/init.lua b/modules/home/rsydn/programs/nvim/init.lua index 2514f9e..40f66c5 100644 --- a/modules/home/rsydn/programs/nvim/init.lua +++ b/modules/home/rsydn/programs/nvim/init.lua @@ -1,2 +1,9 @@ --- bootstrap lazy.nvim, LazyVim and your plugins +-- Load configuration +require("config.options") +require("config.keymaps") +require("config.autocmds") + +-- Load LazyVim utilities before lazy plugin manager +require("config.lazyvim") + require("config.lazy") diff --git a/modules/home/rsydn/programs/nvim/lua/config/autocmds.lua b/modules/home/rsydn/programs/nvim/lua/config/autocmds.lua index 4221e75..d46a7a1 100644 --- a/modules/home/rsydn/programs/nvim/lua/config/autocmds.lua +++ b/modules/home/rsydn/programs/nvim/lua/config/autocmds.lua @@ -1,8 +1,9 @@ --- Autocmds are automatically loaded on the VeryLazy event --- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua --- --- Add any additional autocmds here --- with `vim.api.nvim_create_autocmd` --- --- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults) --- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell") +-- Essential autocommands (minimal) +local autocmd = vim.api.nvim_create_autocmd + +-- Highlight on yank +autocmd("TextYankPost", { + callback = function() + vim.highlight.on_yank() + end, +}) diff --git a/modules/home/rsydn/programs/nvim/lua/config/keymaps.lua b/modules/home/rsydn/programs/nvim/lua/config/keymaps.lua index 2c134f7..6ee10ee 100644 --- a/modules/home/rsydn/programs/nvim/lua/config/keymaps.lua +++ b/modules/home/rsydn/programs/nvim/lua/config/keymaps.lua @@ -1,3 +1,9 @@ --- Keymaps are automatically loaded on the VeryLazy event --- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua --- Add any additional keymaps here +-- Essential keymaps (minimal improvements over default Vim) +local keymap = vim.keymap + +-- Clear search highlight with +keymap.set("n", "", "noh", { desc = "Clear search highlight" }) + +-- Better indenting (stay in visual mode) +keymap.set("v", "<", "", ">gv") diff --git a/modules/home/rsydn/programs/nvim/lua/config/lazy.lua b/modules/home/rsydn/programs/nvim/lua/config/lazy.lua index d73bfa1..2c4b53e 100644 --- a/modules/home/rsydn/programs/nvim/lua/config/lazy.lua +++ b/modules/home/rsydn/programs/nvim/lua/config/lazy.lua @@ -13,36 +13,35 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then end end vim.opt.rtp:prepend(lazypath) - +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" require("lazy").setup({ spec = { - -- add LazyVim and import its plugins - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - -- import/override with your plugins + { + "LazyVim/LazyVim", + import = "lazyvim.plugins", + }, + { import = "plugins" }, }, + + defaults = { - -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. - -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. lazy = false, - -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, - -- have outdated releases, which may break your Neovim install. - version = false, -- always use the latest git commit - -- version = "*", -- try installing the latest stable version for plugins that support semver + version = false, }, - install = { colorscheme = { "tokyonight", "habamax" } }, - checker = { - enabled = true, -- check for plugin updates periodically - notify = false, -- notify on update - }, -- automatically check for plugin updates + + install = { colorscheme = { "gruvbox", "habamax" } }, + + checker = { enabled = false }, + change_detection = { notify = false }, performance = { rtp = { - -- disable some rtp plugins disabled_plugins = { "gzip", - -- "matchit", - -- "matchparen", - -- "netrwPlugin", + "matchit", + "matchparen", + "netrwPlugin", "tarPlugin", "tohtml", "tutor", diff --git a/modules/home/rsydn/programs/nvim/lua/config/lazyvim/init.lua b/modules/home/rsydn/programs/nvim/lua/config/lazyvim/init.lua new file mode 100644 index 0000000..6e5fe14 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/config/lazyvim/init.lua @@ -0,0 +1,53 @@ +-- LazyVim utilities module +-- Provides helper functions for plugin configuration + +local M = {} + +-- Mini module utilities +M.mini = {} + +-- Setup mini.pairs with given options +function M.mini.pairs(opts) + require("mini.pairs").setup(opts) +end + +-- Text object for entire buffer +M.mini.ai_buffer = function(ai) + local n_lines = vim.fn.line("$") + local start_line, end_line = 1, n_lines + if n_lines == 0 then + return { from = { line = 0, col = 0 } } + end + local start_col, end_col = 1, math.max(vim.fn.getline(end_line):len(), 1) + return { + from = { line = start_line, col = start_col }, + to = { line = end_line, col = end_col }, + } +end + +-- Text object hints are now handled by mini.clue + +-- Run callback when plugin is loaded +function M.on_load(name, fn) + local Config = require("lazy.core.config") + if Config.plugins[name] and Config.plugins[name]._.loaded then + vim.schedule(function() + fn(name) + end) + else + vim.api.nvim_create_autocmd("User", { + pattern = "LazyLoad", + callback = function(event) + if event.data == name then + fn(name) + return true + end + end, + }) + end +end + +-- Make LazyVim global +_G.LazyVim = M + +return M diff --git a/modules/home/rsydn/programs/nvim/lua/config/options.lua b/modules/home/rsydn/programs/nvim/lua/config/options.lua index 3ea1454..332532c 100644 --- a/modules/home/rsydn/programs/nvim/lua/config/options.lua +++ b/modules/home/rsydn/programs/nvim/lua/config/options.lua @@ -1,3 +1,38 @@ --- Options are automatically loaded before lazy.nvim startup --- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua --- Add any additional options here +-- Minimal essential options +local opt = vim.opt + +-- Leader keys +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" + +-- Line numbers +opt.number = true +opt.relativenumber = true + +-- Indentation +opt.tabstop = 2 +opt.shiftwidth = 2 +opt.expandtab = true +opt.smartindent = true + +-- Search +opt.ignorecase = true +opt.smartcase = true + +-- UI +opt.termguicolors = true +opt.signcolumn = "yes" +opt.cursorline = true + +-- Splits +opt.splitbelow = true +opt.splitright = true + +-- Clipboard +opt.clipboard = "unnamedplus" + +-- Undo +opt.undofile = true + +-- Mouse +opt.mouse = "a" diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/coding.lua b/modules/home/rsydn/programs/nvim/lua/plugins/coding.lua new file mode 100644 index 0000000..39dcab5 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/coding.lua @@ -0,0 +1,80 @@ +return { + -- Auto pairs + -- Automatically inserts a matching closing character + -- when you type an opening character like `"`, `[`, or `(`. + { + "nvim-mini/mini.pairs", + event = "VeryLazy", + opts = { + modes = { insert = true, command = true, terminal = false }, + -- skip autopair when next character is one of these + skip_next = [=[[%w%%%'%[%"%%.%`%$]]=], + -- skip autopair when the cursor is inside these treesitter nodes + skip_ts = { "string" }, + -- skip autopair when next character is closing pair + -- and there are more closing pairs than opening pairs + skip_unbalanced = true, + -- better deal with markdown code blocks + markdown = true, + }, + config = function(_, opts) + LazyVim.mini.pairs(opts) + end, + }, + + -- Improves comment syntax, lets Neovim handle multiple + -- types of comments for a single language, and relaxes rules + -- for uncommenting. + { + "folke/ts-comments.nvim", + event = "VeryLazy", + opts = {}, + }, + + -- Extends the a & i text objects, this adds the ability to select + -- arguments, function calls, text within quotes and brackets + { + "nvim-mini/mini.ai", + event = "VeryLazy", + opts = function() + local ai = require("mini.ai") + return { + n_lines = 500, + custom_textobjects = { + o = ai.gen_spec.treesitter({ + a = { "@block.outer", "@conditional.outer", "@loop.outer" }, + i = { "@block.inner", "@conditional.inner", "@loop.inner" }, + }), + f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }), + c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }), + t = { "<(%p%w-)%f[^<%w][^<>]->.*()$" }, + d = { "%f[%d]%d+" }, + e = { { "%u[%l%d]+%f[^%l%d]", "%f[%S][%l%d]+%f[^%l%d]" }, "^().*()$" }, + g = LazyVim.mini.ai_buffer, + u = ai.gen_spec.function_call(), + U = ai.gen_spec.function_call({ name_pattern = "[%w_]" }), + }, + } + end, + config = function(_, opts) + require("mini.ai").setup(opts) + -- mini.clue handles text object hints automatically + end, + }, + + -- Configures LuaLS to support auto-completion and type checking + -- while editing your Neovim configuration. + { + "folke/lazydev.nvim", + ft = "lua", + cmd = "LazyDev", + opts = { + library = { + { path = "${3rd}/luv/library", words = { "vim.uv" } }, + { path = "LazyVim", words = { "LazyVim" } }, + { path = "snacks.nvim", words = { "Snacks" } }, + { path = "lazy.nvim", words = { "LazyVim" } }, + }, + }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/colorscheme.lua b/modules/home/rsydn/programs/nvim/lua/plugins/colorscheme.lua new file mode 100644 index 0000000..56fb218 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/colorscheme.lua @@ -0,0 +1,75 @@ +return { + -- gruvbox + { + "ellisonleao/gruvbox.nvim", + lazy = false, + priority = 1000, + opts = {}, + config = function() + require("gruvbox").setup({}) + vim.cmd.colorscheme("gruvbox") + end, + }, + + -- tokyonight + { + "folke/tokyonight.nvim", + lazy = true, + opts = { style = "moon" }, + }, + + -- catppuccin + { + "catppuccin/nvim", + lazy = true, + priority = 1000, + name = "catppuccin", + opts = { + lsp_styles = { + underlines = { + errors = { "undercurl" }, + hints = { "undercurl" }, + warnings = { "undercurl" }, + information = { "undercurl" }, + }, + }, + -- integrations = { + -- aerial = true, + -- alpha = true, + -- cmp = true, + -- dashboard = true, + -- flash = true, + -- fzf = true, + -- grug_far = true, + -- gitsigns = true, + -- headlines = true, + -- illuminate = true, + -- indent_blankline = { enabled = true }, + -- leap = true, + -- lsp_trouble = true, + -- mason = true, + -- mini = true, + -- navic = { enabled = true, custom_bg = "lualine" }, + -- neotest = true, + -- neotree = true, + -- noice = true, + -- notify = true, + -- snacks = true, + -- telescope = true, + -- treesitter_context = true, + -- which_key = true, + -- }, + }, + -- specs = { + -- { + -- "akinsho/bufferline.nvim", + -- optional = true, + -- opts = function(_, opts) + -- if (vim.g.colors_name or ""):find("catppuccin") then + -- opts.highlights = require("catppuccin.special.bufferline").get_theme() + -- end + -- end, + -- }, + -- }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/completion.lua b/modules/home/rsydn/programs/nvim/lua/plugins/completion.lua new file mode 100644 index 0000000..6890957 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/completion.lua @@ -0,0 +1,48 @@ +return { + -- Modern completion engine with built-in fuzzy matching + -- Note: Installed via Nix with pre-built Rust backend (see neovim.nix) + { + "saghen/blink.cmp", + dependencies = { + "rafamadriz/friendly-snippets", + }, + version = "1.*", + event = "InsertEnter", + build = nil, -- Disable build since Nix provides pre-compiled version + opts = { + -- Keymap preset options: 'default' | 'super-tab' | 'enter' + keymap = { preset = "default" }, + + appearance = { + -- Use mono nerd font variant + nerd_font_variant = "mono", + }, + + -- Default completion sources + sources = { + default = { "lsp", "path", "snippets", "buffer" }, + }, + + completion = { + documentation = { + auto_show = true, + auto_show_delay_ms = 500, + }, + menu = { + draw = { + columns = { { "label", "label_description", gap = 1 }, { "kind_icon", "kind" } }, + }, + }, + }, + + -- Fuzzy matching implementation + -- Using "rust" since Nix provides pre-built native module + fuzzy = { + use_typo_resistance = true, + use_frecency = true, + use_proximity = true, + }, + }, + opts_extend = { "sources.default" }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/dashboard.lua b/modules/home/rsydn/programs/nvim/lua/plugins/dashboard.lua new file mode 100644 index 0000000..405e814 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/dashboard.lua @@ -0,0 +1,33 @@ +return { + { + "folke/snacks.nvim", + opts = { + dashboard = { + preset = { + header = [[ +⣿⡇⠉⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠈⠛⢿⣿⣿⣿⣿⣿ +⣿⡇⠀⠀⠀⠀⣉⡑⠺⢷⣍⢻⣿⣿⣿⣿⣿⡿⢿⣛⣻⣭⣭⣹⣏⣭⣍⣙⡛⠿⠀⠀⠿⠆⠀⠹⢿⣿⣿⣿ +⣿⡇⢠⠀⡟⣼⣿⣿⣶⣤⡈⠑⠛⣿⢟⣯⣷⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣙⠛⢿⡄⣄⠈⠹⣿⣿ +⣿⣧⠈⠀⣸⣿⣿⣿⣿⣿⣿⡗⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠃⣿⣷⡄⠈⢻ +⣿⣿⠀⢠⣿⣿⣿⣿⣿⣿⠏⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢻⣿⣿⣿⣿⣿⣿⣷⡜⢿⣿⣦⡀ +⣿⣿⡄⣼⣿⣿⣿⣿⣿⠋⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⣿⣿⣿⢈⠻⣿⣿⣿⣿⣿⣿⣿⣎⢻⣿⣿ +⣿⣿⢧⣿⣿⣿⣿⣿⠃⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⡆⢿⣿⣿⡆⣷⣌⠻⣿⣿⣿⣿⣿⣿⣆⢻⢃ +⣿⣿⢸⣿⣿⣿⣿⣷⡄⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢣⣾⡇⢸⣿⣿⡇⢿⣿⣷⣌⢻⠿⣿⣿⣿⣿⡄⢀ +⣿⡏⣿⣿⣿⣿⣿⣿⡇⢰⠰⣙⢿⣿⣿⣿⣿⣿⣍⠙⠱⢿⣿⣿⢸⣿⡿⡇⢸⣿⡿⢛⣥⡘⢿⣿⠿⣿⣿⠘ +⣿⢣⣿⣿⣿⣿⣿⣿⠇⢸⣧⠙⠿⢿⣿⣿⣿⡿⠋⠘⠛⠒⠈⠙⡀⣞⡰⡇⣙⡅⠚⡉⠡⢠⣄⠹⠐⣮⡻⢇ +⣿⣸⣿⣿⣿⣿⣿⣿⠀⡜⡇⣾⡝⣼⣿⣿⢟⣵⡏⠀⠀⠛⠀⣸⣇⠙⣠⢠⣿⠀⡀⠁⢀⣼⡏⣠⠁⢿⣿⣦ +⡇⣿⣿⣿⣿⣿⣿⣿⠀⣿⡆⣿⢣⡿⢿⣷⡎⣿⣿⣦⣀⡤⢴⣿⣿⣴⣿⣿⣿⣷⡲⠶⠿⢻⢁⣿⢠⣼⣿⣿ +⢳⣿⣿⣿⣿⣿⣿⣿⢰⣿⡿⠌⠈⢼⣎⢻⡇⢻⣷⣶⣶⣾⣿⣿⡿⢫⣍⣛⢻⣿⣿⣿⣿⡏⢸⡿⢸⣿⣿⣿ +⣼⣿⣿⣿⣿⣿⣿⡇⣾⢏⣾⣷⣶⣶⣬⡀⢻⠘⢿⣿⣿⣿⣿⡿⢡⣿⣿⡟⣸⣿⣿⡿⢟⡅⢻⡇⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⡿⢰⣿⣸⣿⣿⣿⣿⣿⣿⢠⠂⣷⣬⡛⠿⣿⢃⣿⣿⣿⢣⠿⠛⣩⣴⣿⣧⠸⢰⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⣿⢃⣿⡏⣿⣿⣿⣿⣿⣿⣿⠘⢧⣸⣿⣷⡀⣠⡦⣭⡍⣤⣶⣾⣧⢸⣿⣿⣿⢠⣾⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⠏⣼⣿⡇⣿⣿⣿⣿⣿⡿⣿⠸⣮⡻⣿⡟⣴⡿⠇⣿⢃⣿⣿⣿⣿⡈⣿⣿⣿⢸⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⡆⣿⣿⣇⣿⣿⣿⣿⣿⡇⣿⡆⣿⣷⣽⣷⣩⣶⠇⣿⢸⣿⣿⣿⣿⡇⣿⣿⣿⢸⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⡇⣿⣿⢻⣿⣿⣿⣿⣿⡇⣿⣧⢹⣿⣿⣿⣿⡿⣸⡏⢚⣽⣿⣿⣿⣇⢸⣿⣿⣾⣿⣿⣿⣿⣿ +⣿⣿⣿⣿⣿⡇⣿⢏⢸⣿⣿⣿⣿⣿⢠⣿⣿⣮⡻⠿⡿⠟⣱⣿⡇⢸⣿⣿⣿⣿⣿⠸⣿⣿⢹⣿⣿⣿⣿⣿ + ]], + }, + }, + }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/example.lua b/modules/home/rsydn/programs/nvim/lua/plugins/example.lua deleted file mode 100644 index 17f53d6..0000000 --- a/modules/home/rsydn/programs/nvim/lua/plugins/example.lua +++ /dev/null @@ -1,197 +0,0 @@ --- since this is just an example spec, don't actually load anything here and return an empty spec --- stylua: ignore -if true then return {} end - --- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim --- --- In your plugin files, you can: --- * add extra plugins --- * disable/enabled LazyVim plugins --- * override the configuration of LazyVim plugins -return { - -- add gruvbox - { "ellisonleao/gruvbox.nvim" }, - - -- Configure LazyVim to load gruvbox - { - "LazyVim/LazyVim", - opts = { - colorscheme = "gruvbox", - }, - }, - - -- change trouble config - { - "folke/trouble.nvim", - -- opts will be merged with the parent spec - opts = { use_diagnostic_signs = true }, - }, - - -- disable trouble - { "folke/trouble.nvim", enabled = false }, - - -- override nvim-cmp and add cmp-emoji - { - "hrsh7th/nvim-cmp", - dependencies = { "hrsh7th/cmp-emoji" }, - ---@param opts cmp.ConfigSchema - opts = function(_, opts) - table.insert(opts.sources, { name = "emoji" }) - end, - }, - - -- change some telescope options and a keymap to browse plugin files - { - "nvim-telescope/telescope.nvim", - keys = { - -- add a keymap to browse plugin files - -- stylua: ignore - { - "fp", - function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end, - desc = "Find Plugin File", - }, - }, - -- change some options - opts = { - defaults = { - layout_strategy = "horizontal", - layout_config = { prompt_position = "top" }, - sorting_strategy = "ascending", - winblend = 0, - }, - }, - }, - - -- add pyright to lspconfig - { - "neovim/nvim-lspconfig", - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- pyright will be automatically installed with mason and loaded with lspconfig - pyright = {}, - }, - }, - }, - - -- add tsserver and setup with typescript.nvim instead of lspconfig - { - "neovim/nvim-lspconfig", - dependencies = { - "jose-elias-alvarez/typescript.nvim", - init = function() - require("lazyvim.util").lsp.on_attach(function(_, buffer) - -- stylua: ignore - vim.keymap.set( "n", "co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" }) - vim.keymap.set("n", "cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer }) - end) - end, - }, - ---@class PluginLspOpts - opts = { - ---@type lspconfig.options - servers = { - -- tsserver will be automatically installed with mason and loaded with lspconfig - tsserver = {}, - }, - -- you can do any additional lsp server setup here - -- return true if you don't want this server to be setup with lspconfig - ---@type table - setup = { - -- example to setup with typescript.nvim - tsserver = function(_, opts) - require("typescript").setup({ server = opts }) - return true - end, - -- Specify * to use this function as a fallback for any server - -- ["*"] = function(server, opts) end, - }, - }, - }, - - -- for typescript, LazyVim also includes extra specs to properly setup lspconfig, - -- treesitter, mason and typescript.nvim. So instead of the above, you can use: - { import = "lazyvim.plugins.extras.lang.typescript" }, - - -- add more treesitter parsers - { - "nvim-treesitter/nvim-treesitter", - opts = { - ensure_installed = { - "bash", - "html", - "javascript", - "json", - "lua", - "markdown", - "markdown_inline", - "python", - "query", - "regex", - "tsx", - "typescript", - "vim", - "yaml", - }, - }, - }, - - -- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above - -- would overwrite `ensure_installed` with the new value. - -- If you'd rather extend the default config, use the code below instead: - { - "nvim-treesitter/nvim-treesitter", - opts = function(_, opts) - -- add tsx and treesitter - vim.list_extend(opts.ensure_installed, { - "tsx", - "typescript", - }) - end, - }, - - -- the opts function can also be used to change the default opts: - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function(_, opts) - table.insert(opts.sections.lualine_x, { - function() - return "😄" - end, - }) - end, - }, - - -- or you can return new options to override all the defaults - { - "nvim-lualine/lualine.nvim", - event = "VeryLazy", - opts = function() - return { - --[[add your custom lualine config here]] - } - end, - }, - - -- use mini.starter instead of alpha - { import = "lazyvim.plugins.extras.ui.mini-starter" }, - - -- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc - { import = "lazyvim.plugins.extras.lang.json" }, - - -- add any tools you want to have installed below - { - "williamboman/mason.nvim", - opts = { - ensure_installed = { - "stylua", - "shellcheck", - "shfmt", - "flake8", - }, - }, - }, -} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/file-explorer.lua b/modules/home/rsydn/programs/nvim/lua/plugins/file-explorer.lua new file mode 100644 index 0000000..6b1bb5e --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/file-explorer.lua @@ -0,0 +1,56 @@ +return { + -- Telescope - Fuzzy finder over lists + { + "nvim-telescope/telescope.nvim", + tag = "0.1.8", + dependencies = { + "nvim-lua/plenary.nvim", + }, + cmd = "Telescope", + keys = { + { "ff", "Telescope find_files", desc = "Find Files" }, + { "fg", "Telescope live_grep", desc = "Live Grep" }, + { "fb", "Telescope buffers", desc = "Buffers" }, + { "fh", "Telescope help_tags", desc = "Help Tags" }, + }, + opts = { + defaults = { + -- Removed which_key mapping - mini.clue handles keybind hints globally + }, + }, + }, + + -- Telescope FZF native - Better sorting performance + -- Note: Installed via Nix (see neovim.nix) to avoid build issues + { + "nvim-telescope/telescope-fzf-native.nvim", + dependencies = { "nvim-telescope/telescope.nvim" }, + config = function() + require("telescope").load_extension("fzf") + end, + }, + + -- Neo-tree - File explorer tree + { + "nvim-neo-tree/neo-tree.nvim", + branch = "v3.x", + dependencies = { + "nvim-lua/plenary.nvim", + "MunifTanjim/nui.nvim", + "nvim-tree/nvim-web-devicons", + }, + cmd = "Neotree", + keys = { + { "e", "Neotree toggle", desc = "Toggle Neo-tree" }, + { "o", "Neotree focus", desc = "Focus Neo-tree" }, + }, + opts = { + filesystem = { + follow_current_file = { + enabled = true, + }, + use_libuv_file_watcher = true, + }, + }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/formatting.lua b/modules/home/rsydn/programs/nvim/lua/plugins/formatting.lua new file mode 100644 index 0000000..2e8ed38 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/formatting.lua @@ -0,0 +1,59 @@ +return { + { + "stevearc/conform.nvim", + event = { "BufWritePre" }, + cmd = { "ConformInfo" }, + keys = { + { + "cf", + function() + require("conform").format({ async = true, lsp_fallback = true }) + end, + mode = { "n", "v" }, + desc = "Format buffer", + }, + }, + opts = { + formatters_by_ft = { + lua = { "stylua" }, + nix = { "nixfmt" }, + python = { "ruff_format", "ruff_organize_imports" }, + javascript = { "prettierd", "prettier", stop_after_first = true }, + typescript = { "prettierd", "prettier", stop_after_first = true }, + javascriptreact = { "prettierd", "prettier", stop_after_first = true }, + typescriptreact = { "prettierd", "prettier", stop_after_first = true }, + json = { "prettierd", "prettier", stop_after_first = true }, + jsonc = { "prettierd", "prettier", stop_after_first = true }, + yaml = { "prettierd", "prettier", stop_after_first = true }, + markdown = { "prettierd", "prettier", stop_after_first = true }, + html = { "prettierd", "prettier", stop_after_first = true }, + css = { "prettierd", "prettier", stop_after_first = true }, + scss = { "prettierd", "prettier", stop_after_first = true }, + rust = { "rustfmt" }, + go = { "gofumpt" }, + sh = { "shfmt" }, + bash = { "shfmt" }, + zsh = { "shfmt" }, + }, + -- Format on save + format_on_save = { + timeout_ms = 500, + lsp_fallback = true, + }, + -- Customize formatters + formatters = { + shfmt = { + prepend_args = { "-i", "2" }, -- 2 space indent + }, + ruff_format = { + command = "ruff", + args = { "format", "--stdin-filename", "$FILENAME" }, + }, + ruff_organize_imports = { + command = "ruff", + args = { "check", "--select", "I", "--fix", "--stdin-filename", "$FILENAME" }, + }, + }, + }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/linting.lua b/modules/home/rsydn/programs/nvim/lua/plugins/linting.lua new file mode 100644 index 0000000..e0b931a --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/linting.lua @@ -0,0 +1,58 @@ +return { + { + "mfussenegger/nvim-lint", + event = { "BufReadPost", "BufNewFile", "BufWritePost" }, + opts = { + events = { "BufWritePost", "BufReadPost", "InsertLeave" }, + linters_by_ft = { + javascript = { "eslint" }, + typescript = { "eslint" }, + javascriptreact = { "eslint" }, + typescriptreact = { "eslint" }, + python = { "ruff" }, + sh = { "shellcheck" }, + bash = { "shellcheck" }, + }, + linters = {}, + }, + config = function(_, opts) + local lint = require("lint") + + -- Merge custom linter configs + for name, linter in pairs(opts.linters) do + if type(linter) == "table" and type(lint.linters[name]) == "table" then + lint.linters[name] = vim.tbl_deep_extend("force", lint.linters[name], linter) + else + lint.linters[name] = linter + end + end + + lint.linters_by_ft = opts.linters_by_ft + + -- Debounced lint function with proper timer management + local timer = vim.uv.new_timer() + local function debounce_lint() + -- Stop existing timer before starting new one to prevent EALREADY error + timer:stop() + timer:start(100, 0, vim.schedule_wrap(lint.try_lint)) + end + + -- Create autocommand for linting + vim.api.nvim_create_autocmd(opts.events, { + group = vim.api.nvim_create_augroup("nvim-lint", { clear = true }), + callback = debounce_lint, + }) + + -- Clean up timer on exit + vim.api.nvim_create_autocmd("VimLeavePre", { + group = vim.api.nvim_create_augroup("nvim-lint-cleanup", { clear = true }), + callback = function() + if timer and not timer:is_closing() then + timer:stop() + timer:close() + end + end, + }) + end, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/lsp.lua b/modules/home/rsydn/programs/nvim/lua/plugins/lsp.lua new file mode 100644 index 0000000..ea48081 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/lsp.lua @@ -0,0 +1,106 @@ +-- LSP configuration using Nix-managed servers +return { + -- Disable Mason plugins (we use Nix-managed servers instead) + { "mason-org/mason.nvim", enabled = false }, + { "mason-org/mason-lspconfig.nvim", enabled = false }, + { "jay-babu/mason-null-ls.nvim", enabled = false }, + { "jay-babu/mason-nvim-dap.nvim", enabled = false }, + + { + "neovim/nvim-lspconfig", + event = { "BufReadPre", "BufNewFile" }, + dependencies = { + "saghen/blink.cmp", -- For LSP capabilities + }, + config = function() + -- Get blink.cmp capabilities + local capabilities = require("blink.cmp").get_lsp_capabilities() + + -- Common LSP attach keybindings + vim.api.nvim_create_autocmd("LspAttach", { + group = vim.api.nvim_create_augroup("UserLspConfig", {}), + callback = function(ev) + local opts = { buffer = ev.buf } + vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) + vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) + vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) + vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) + vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) + vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) + vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) + vim.keymap.set("n", "d", vim.diagnostic.open_float, opts) + vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts) + vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts) + end, + }) + + -- Configure each LSP server + local lspconfig = require("lspconfig") + + -- Lua + lspconfig.lua_ls.setup({ + capabilities = capabilities, + settings = { + Lua = { + runtime = { version = "LuaJIT" }, + diagnostics = { globals = { "vim" } }, + workspace = { + library = vim.api.nvim_get_runtime_file("", true), + checkThirdParty = false, + }, + telemetry = { enable = false }, + }, + }, + }) + + -- Nix + lspconfig.nil_ls.setup({ + capabilities = capabilities, + settings = { + ["nil"] = { + formatting = { command = { "nixfmt" } }, + }, + }, + }) + + -- Python + lspconfig.pyright.setup({ + capabilities = capabilities, + settings = { + python = { + analysis = { + typeCheckingMode = "basic", + autoSearchPaths = true, + useLibraryCodeForTypes = true, + }, + }, + }, + }) + + -- TypeScript/JavaScript + lspconfig.ts_ls.setup({ + capabilities = capabilities, + }) + + -- Rust + lspconfig.rust_analyzer.setup({ + capabilities = capabilities, + settings = { + ["rust-analyzer"] = { + checkOnSave = { command = "clippy" }, + }, + }, + }) + + -- Go + lspconfig.gopls.setup({ + capabilities = capabilities, + }) + + -- C/C++ + lspconfig.clangd.setup({ + capabilities = capabilities, + }) + end, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/smear_cursor.lua b/modules/home/rsydn/programs/nvim/lua/plugins/smear_cursor.lua new file mode 100644 index 0000000..69fd054 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/smear_cursor.lua @@ -0,0 +1,4 @@ +return { + "sphamba/smear-cursor.nvim", + opts = {}, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/treesitter.lua b/modules/home/rsydn/programs/nvim/lua/plugins/treesitter.lua new file mode 100644 index 0000000..8573216 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/treesitter.lua @@ -0,0 +1,51 @@ +return { + { + "nvim-treesitter/nvim-treesitter", + opts = { + ensure_installed = { + "bash", + "c", + "cpp", + "css", + "diff", + "dockerfile", + "git_config", + "git_rebase", + "gitcommit", + "gitignore", + "go", + "gomod", + "gosum", + "html", + "javascript", + "jsdoc", + "json", + "jsonc", + "latex", + "lua", + "luadoc", + "luap", + "markdown", + "markdown_inline", + "nix", + "norg", + "printf", + "python", + "query", + "regex", + "rust", + "scss", + "svelte", + "toml", + "tsx", + "typescript", + "typst", + "vim", + "vimdoc", + "vue", + "xml", + "yaml", + }, + }, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/ui.lua b/modules/home/rsydn/programs/nvim/lua/plugins/ui.lua new file mode 100644 index 0000000..60b5122 --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/ui.lua @@ -0,0 +1,174 @@ +return { + -- Better UI for messages, cmdline and the popupmenu + { + "folke/noice.nvim", + event = "VeryLazy", + opts = { + lsp = { + override = { + ["vim.lsp.util.convert_input_to_markdown_lines"] = true, + ["vim.lsp.util.stylize_markdown"] = true, + ["cmp.entry.get_documentation"] = true, + }, + }, + routes = { + { + filter = { + event = "msg_show", + any = { + { find = "%d+L, %d+B" }, + { find = "; after #%d+" }, + { find = "; before #%d+" }, + }, + }, + view = "mini", + }, + }, + presets = { + bottom_search = true, + command_palette = true, + long_message_to_split = true, + }, + }, + keys = { + { "sn", "", desc = "+noice" }, + { "snl", function() require("noice").cmd("last") end, desc = "Noice Last Message" }, + { "snh", function() require("noice").cmd("history") end, desc = "Noice History" }, + { "sna", function() require("noice").cmd("all") end, desc = "Noice All" }, + { "snd", function() require("noice").cmd("dismiss") end, desc = "Dismiss All" }, + }, + dependencies = { + "MunifTanjim/nui.nvim", + }, + }, + + -- Statusline + { + "nvim-lualine/lualine.nvim", + event = "VeryLazy", + opts = function() + return { + options = { + theme = "auto", + globalstatus = true, + disabled_filetypes = { statusline = { "dashboard", "alpha", "starter" } }, + }, + sections = { + lualine_a = { "mode" }, + lualine_b = { "branch" }, + lualine_c = { + { + "diagnostics", + symbols = { + error = " ", + warn = " ", + info = " ", + hint = " ", + }, + }, + { "filetype", icon_only = true, separator = "", padding = { left = 1, right = 0 } }, + { "filename", path = 1, symbols = { modified = " ", readonly = "", unnamed = "" } }, + }, + lualine_x = { + { + "diff", + symbols = { + added = " ", + modified = " ", + removed = " ", + }, + }, + }, + lualine_y = { + { "progress", separator = " ", padding = { left = 1, right = 0 } }, + { "location", padding = { left = 0, right = 1 } }, + }, + lualine_z = { + function() + return " " .. os.date("%R") + end, + }, + }, + extensions = { "lazy" }, + } + end, + }, + + -- Bufferline + { + "akinsho/bufferline.nvim", + event = "VeryLazy", + keys = { + { "bp", "BufferLineTogglePin", desc = "Toggle Pin" }, + { "bP", "BufferLineGroupClose ungrouped", desc = "Delete Non-Pinned Buffers" }, + { "bo", "BufferLineCloseOthers", desc = "Delete Other Buffers" }, + { "br", "BufferLineCloseRight", desc = "Delete Buffers to the Right" }, + { "bl", "BufferLineCloseLeft", desc = "Delete Buffers to the Left" }, + { "", "BufferLineCyclePrev", desc = "Prev Buffer" }, + { "", "BufferLineCycleNext", desc = "Next Buffer" }, + { "[b", "BufferLineCyclePrev", desc = "Prev Buffer" }, + { "]b", "BufferLineCycleNext", desc = "Next Buffer" }, + }, + opts = { + options = { + close_command = function(n) require("mini.bufremove").delete(n, false) end, + right_mouse_command = function(n) require("mini.bufremove").delete(n, false) end, + diagnostics = "nvim_lsp", + always_show_bufferline = false, + offsets = { + { + filetype = "neo-tree", + text = "Neo-tree", + highlight = "Directory", + text_align = "left", + }, + }, + }, + }, + dependencies = { + { + "nvim-mini/mini.bufremove", + keys = { + { "bd", function() require("mini.bufremove").delete(0, false) end, desc = "Delete Buffer" }, + { "bD", function() require("mini.bufremove").delete(0, true) end, desc = "Delete Buffer (Force)" }, + }, + opts = {}, + }, + }, + }, + + -- Indent guides + { + "lukas-reineke/indent-blankline.nvim", + event = { "BufReadPost", "BufNewFile" }, + opts = { + indent = { + char = "│", + tab_char = "│", + }, + scope = { show_start = false, show_end = false }, + exclude = { + filetypes = { + "help", + "alpha", + "dashboard", + "neo-tree", + "Trouble", + "trouble", + "lazy", + "mason", + "notify", + "toggleterm", + "lazyterm", + }, + }, + }, + main = "ibl", + }, + + -- Icons + { + "nvim-tree/nvim-web-devicons", + lazy = true, + }, +} diff --git a/modules/home/rsydn/programs/nvim/lua/plugins/which-key.lua b/modules/home/rsydn/programs/nvim/lua/plugins/which-key.lua new file mode 100644 index 0000000..e79bf9a --- /dev/null +++ b/modules/home/rsydn/programs/nvim/lua/plugins/which-key.lua @@ -0,0 +1,78 @@ +return { + -- Disable which-key (we use mini.clue instead) + { "folke/which-key.nvim", enabled = false }, + + -- mini.clue - Lightweight keybind hints + { + "nvim-mini/mini.clue", + event = "VeryLazy", + config = function() + local miniclue = require("mini.clue") + miniclue.setup({ + triggers = { + -- Leader triggers + { mode = "n", keys = "" }, + { mode = "x", keys = "" }, + + -- Built-in completion + { mode = "i", keys = "" }, + + -- `g` key + { mode = "n", keys = "g" }, + { mode = "x", keys = "g" }, + + -- Marks + { mode = "n", keys = "'" }, + { mode = "n", keys = "`" }, + { mode = "x", keys = "'" }, + { mode = "x", keys = "`" }, + + -- Registers + { mode = "n", keys = '"' }, + { mode = "x", keys = '"' }, + { mode = "i", keys = "" }, + { mode = "c", keys = "" }, + + -- Window commands + { mode = "n", keys = "" }, + + -- `z` key + { mode = "n", keys = "z" }, + { mode = "x", keys = "z" }, + + -- Bracketed commands + { mode = "n", keys = "[" }, + { mode = "n", keys = "]" }, + }, + + clues = { + -- Enhance this by adding descriptions for mapping groups + miniclue.gen_clues.builtin_completion(), + miniclue.gen_clues.g(), + miniclue.gen_clues.marks(), + miniclue.gen_clues.registers(), + miniclue.gen_clues.windows(), + miniclue.gen_clues.z(), + + -- Custom leader key descriptions + { mode = "n", keys = "b", desc = "+buffer" }, + { mode = "n", keys = "c", desc = "+code" }, + { mode = "n", keys = "d", desc = "+diagnostics" }, + { mode = "n", keys = "e", desc = "+explorer" }, + { mode = "n", keys = "f", desc = "+find" }, + { mode = "n", keys = "o", desc = "+open" }, + { mode = "n", keys = "r", desc = "+rename" }, + { mode = "n", keys = "s", desc = "+search" }, + }, + + window = { + delay = 300, -- Show hints after 300ms + config = { + width = "auto", + border = "rounded", + }, + }, + }) + end, + }, +} diff --git a/modules/home/rsydn/programs/nvim/stylua.toml b/modules/home/rsydn/programs/nvim/stylua.toml deleted file mode 100644 index 5d6c50d..0000000 --- a/modules/home/rsydn/programs/nvim/stylua.toml +++ /dev/null @@ -1,3 +0,0 @@ -indent_type = "Spaces" -indent_width = 2 -column_width = 120 \ No newline at end of file diff --git a/modules/home/rsydn/shell/fish.nix b/modules/home/rsydn/shell/fish.nix index a413eb2..efa494c 100644 --- a/modules/home/rsydn/shell/fish.nix +++ b/modules/home/rsydn/shell/fish.nix @@ -1,6 +1,4 @@ { config, pkgs, lib, ... }: { - imports = [ ./oh-my-posh ]; - programs.fish = { enable = true; interactiveShellInit = '' @@ -10,8 +8,6 @@ ''; }; - programs.oh-my-posh.enableFishIntegration = lib.mkDefault true; - # Ensure fish is available for login shells on Linux hosts. home.packages = lib.mkAfter [ pkgs.fish ]; } diff --git a/modules/home/rsydn/shell/nushell.nix b/modules/home/rsydn/shell/nushell.nix index a8c594d..4b1062d 100644 --- a/modules/home/rsydn/shell/nushell.nix +++ b/modules/home/rsydn/shell/nushell.nix @@ -1,6 +1,7 @@ { config, pkgs, lib, ... }: let profileBin = "${config.home.profileDirectory}/bin"; + # System binaries path - same on both NixOS and Darwin systemBin = "/run/current-system/sw/bin"; defaultBin = "/nix/var/nix/profiles/default/bin"; darwinHomebrewDir = if pkgs.stdenv.hostPlatform.isAarch64 then @@ -25,50 +26,55 @@ let formatPathList = paths: lib.concatMapStrings (path: " \"${path}\"\n") paths; in { - imports = [ ./oh-my-posh ]; + imports = [ ./starship ]; programs.nushell.enable = lib.mkDefault true; programs.nushell.extraConfig = '' # Dotfiles QA validation command - def dotfiles-qa [] { - let dotfiles_dir = "${config.home.homeDirectory}/Development/dotfiles" + def dotfiles-qa [] { + let dotfiles_dir = "${config.home.homeDirectory}/Development/dotfiles" - print $"(ansi green_bold)Running dotfiles QA validation...(ansi reset)\n" + print $"(ansi green_bold)Running dotfiles QA validation...(ansi reset)\n" - # Step 1: Format check - print $"(ansi blue)1. Formatting nix files...(ansi reset)" - cd $dotfiles_dir - nix fmt . - if $env.LAST_EXIT_CODE != 0 { - print $"(ansi red_bold)✗ Formatting failed(ansi reset)" - return + # Step 1: Format check + print $"(ansi blue)1. Formatting nix files...(ansi reset)" + cd $dotfiles_dir + nix fmt . + if $env.LAST_EXIT_CODE != 0 { + print $"(ansi red_bold)✗ Formatting failed(ansi reset)" + return + } + print $"(ansi green)✓ Formatting complete(ansi reset)\n" + + # Step 2: Flake check + print $"(ansi blue)2. Running flake check...(ansi reset)" + nix flake check + if $env.LAST_EXIT_CODE != 0 { + print $"(ansi red_bold)✗ Flake check failed(ansi reset)" + return + } + print $"(ansi green)✓ Flake check passed(ansi reset)\n" + + # Step 3: Build (without activation) + print $"(ansi blue)3. Building darwin configuration (no activation)...(ansi reset)" + darwin-rebuild build --flake $"($dotfiles_dir)#macbook-pro" + if $env.LAST_EXIT_CODE != 0 { + print $"(ansi yellow)⚠ Build had warnings, but may still work(ansi reset)\n" + } else { + print $"(ansi green)✓ Build successful(ansi reset)\n" + } + + print $"(ansi green_bold)✓ Core QA checks passed!(ansi reset)" } - print $"(ansi green)✓ Formatting complete(ansi reset)\n" - - # Step 2: Flake check - print $"(ansi blue)2. Running flake check...(ansi reset)" - nix flake check - if $env.LAST_EXIT_CODE != 0 { - print $"(ansi red_bold)✗ Flake check failed(ansi reset)" - return - } - print $"(ansi green)✓ Flake check passed(ansi reset)\n" - - # Step 3: Build (without activation) - print $"(ansi blue)3. Building darwin configuration (no activation)...(ansi reset)" - darwin-rebuild build --flake $"($dotfiles_dir)#macbook-pro" - if $env.LAST_EXIT_CODE != 0 { - print $"(ansi yellow)⚠ Build had warnings, but may still work(ansi reset)\n" - } else { - print $"(ansi green)✓ Build successful(ansi reset)\n" - } - - print $"(ansi green_bold)✓ Core QA checks passed!(ansi reset)" - } ''; programs.nushell.envFile.text = '' + # Set XDG Base Directory environment variables + $env.XDG_CONFIG_HOME = "${config.xdg.configHome}" + $env.XDG_DATA_HOME = "${config.xdg.dataHome}" + $env.XDG_CACHE_HOME = "${config.xdg.cacheHome}" + let nix_paths = [ ${formatPathList [ profileBin systemBin defaultBin ]} ] @@ -113,6 +119,4 @@ in { load-secret "groq-api-key" "GROQ_API_KEY" load-secret "firecrawl-api-key" "FIRECRAWL_API_KEY" ''; - - programs.oh-my-posh.enableNushellIntegration = lib.mkDefault true; } diff --git a/modules/home/rsydn/shell/oh-my-posh/capr4n.omp.json b/modules/home/rsydn/shell/oh-my-posh/capr4n.omp.json deleted file mode 100644 index a86b29c..0000000 --- a/modules/home/rsydn/shell/oh-my-posh/capr4n.omp.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json", - "blocks": [ - { - "alignment": "right", - "segments": [ - { - "background": "#003543", - "foreground": "#ffffff", - "style": "plain", - "template": " \ue641 {{ .CurrentDate | date .Format }} ", - "type": "time" - }, - { - "background": "#83769c", - "foreground": "#ffffff", - "properties": { - "always_enabled": true - }, - "style": "plain", - "template": " \ueba2 {{ .FormattedMs }} ", - "type": "executiontime" - } - ], - "type": "rprompt" - }, - { - "alignment": "left", - "segments": [ - { - "background": "#61AFEF", - "foreground": "#ffffff", - "properties": { - "display_host": false - }, - "style": "diamond", - "template": "{{if .Root}} \uf0e7 {{.UserName}} {{else}} {{.UserName}} {{end}}", - "trailing_diamond": "\ue0b0", - "type": "session" - }, - { - "background": "#C678DD", - "foreground": "#ffffff", - "powerline_symbol": "\ue0b0", - "properties": { - "folder_icon": "\uf115", - "folder_separator_icon": " \ue0b1 ", - "max_depth": 2, - "style": "agnoster_short" - }, - "style": "powerline", - "template": " {{ .Path }} ", - "type": "path" - }, - { - "background": "#95ffa4", - "foreground": "#193549", - "powerline_symbol": "\ue0b0", - "properties": { - "fetch_status": true - }, - "style": "powerline", - "template": " {{ .HEAD }}{{ if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{- $staged := add .Staging.Added (add .Staging.Modified (add .Staging.Deleted .Staging.Unmerged)) -}}{{ if gt $staged 0 }} ^{{$staged}}{{ end }}{{ if gt .Working.Modified 0 }} ~{{ .Working.Modified }}{{ end }}{{ if gt .Working.Deleted 0 }} -{{ .Working.Deleted }}{{ end }}{{ if gt .Working.Untracked 0 }} +{{ .Working.Untracked }}{{ end }} ", - "type": "git" - } - ], - "type": "prompt" - }, - { - "alignment": "left", - "newline": true, - "segments": [ - { - "foreground": "#61AFEF", - "style": "plain", - "template": "❯ ", - "type": "text" - } - ], - "type": "prompt" - } - ], - "console_title_template": "{{if .Root}} \u26a1 {{end}}{{.UserName}} \u2794 📁{{.Folder}}", - "final_space": true, - "version": 3 -} diff --git a/modules/home/rsydn/shell/oh-my-posh/default.nix b/modules/home/rsydn/shell/oh-my-posh/default.nix deleted file mode 100644 index 4e38644..0000000 --- a/modules/home/rsydn/shell/oh-my-posh/default.nix +++ /dev/null @@ -1,13 +0,0 @@ -{ config, lib, ... }: -let - themeName = "capr4n.omp.json"; - themeSource = ./capr4n.omp.json; - themeConfigPath = "${config.xdg.configHome}/oh-my-posh/${themeName}"; -in { - programs.oh-my-posh = { - enable = lib.mkDefault true; - configFile = themeConfigPath; - }; - - xdg.configFile."oh-my-posh/${themeName}".source = themeSource; -} diff --git a/modules/home/rsydn/shell/starship/default.nix b/modules/home/rsydn/shell/starship/default.nix new file mode 100644 index 0000000..ea83b79 --- /dev/null +++ b/modules/home/rsydn/shell/starship/default.nix @@ -0,0 +1,8 @@ +{ lib, ... }: { + programs.starship = { + enable = lib.mkDefault true; + enableFishIntegration = true; + enableNushellIntegration = true; + settings = lib.importTOML ./starship.toml; + }; +} diff --git a/modules/home/rsydn/shell/starship/starship.toml b/modules/home/rsydn/shell/starship/starship.toml new file mode 100644 index 0000000..1bfc934 --- /dev/null +++ b/modules/home/rsydn/shell/starship/starship.toml @@ -0,0 +1,180 @@ +"$schema" = "https://starship.rs/config-schema.json" + +format = """ +[](color_orange)\ +$os\ +$username\ +[](bg:color_yellow fg:color_orange)\ +$directory\ +[](fg:color_yellow bg:color_aqua)\ +$git_branch\ +$git_status\ +[](fg:color_aqua bg:color_blue)\ +$c\ +$cpp\ +$rust\ +$golang\ +$nodejs\ +$php\ +$java\ +$kotlin\ +$haskell\ +$python\ +[](fg:color_blue bg:color_bg3)\ +$docker_context\ +$conda\ +$pixi\ +[](fg:color_bg3 bg:color_bg1)\ +$time\ +[ ](fg:color_bg1)\ +$line_break$character""" + +palette = "gruvbox_dark" + +[palettes.gruvbox_dark] +color_fg0 = "#fbf1c7" +color_bg1 = "#3c3836" +color_bg3 = "#665c54" +color_blue = "#458588" +color_aqua = "#689d6a" +color_green = "#98971a" +color_orange = "#d65d0e" +color_purple = "#b16286" +color_red = "#cc241d" +color_yellow = "#d79921" + +[os] +disabled = false +style = "bg:color_orange fg:color_fg0" + +[os.symbols] +Windows = "󰍲" +Ubuntu = "󰕈" +SUSE = "" +Raspbian = "󰐿" +Mint = "󰣭" +Macos = "󰀵" +Manjaro = "" +Linux = "󰌽" +Gentoo = "󰣨" +Fedora = "󰣛" +Alpine = "" +Amazon = "" +Android = "" +Arch = "󰣇" +Artix = "󰣇" +EndeavourOS = "" +CentOS = "" +Debian = "󰣚" +Redhat = "󱄛" +RedHatEnterprise = "󱄛" +Pop = "" + +[username] +show_always = true +style_user = "bg:color_orange fg:color_fg0" +style_root = "bg:color_orange fg:color_fg0" +format = "[ $user ]($style)" + +[directory] +style = "fg:color_fg0 bg:color_yellow" +format = "[ $path ]($style)" +truncation_length = 3 +truncation_symbol = "…/" + +[directory.substitutions] +Documents = "󰈙 " +Downloads = " " +Music = "󰝚 " +Pictures = " " +Developer = "󰲋 " + +[git_branch] +symbol = "" +style = "bg:color_aqua" +format = "[[ $symbol $branch ](fg:color_fg0 bg:color_aqua)]($style)" + +[git_status] +style = "bg:color_aqua" +format = "[[($all_status$ahead_behind )](fg:color_fg0 bg:color_aqua)]($style)" + +[nodejs] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[c] +symbol = " " +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[cpp] +symbol = " " +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[rust] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[golang] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[php] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[java] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[kotlin] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[haskell] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[python] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[docker_context] +symbol = "" +style = "bg:color_bg3" +format = "[[ $symbol( $context) ](fg:#83a598 bg:color_bg3)]($style)" + +[conda] +style = "bg:color_bg3" +format = "[[ $symbol( $environment) ](fg:#83a598 bg:color_bg3)]($style)" + +[pixi] +style = "bg:color_bg3" +format = "[[ $symbol( $version)( $environment) ](fg:color_fg0 bg:color_bg3)]($style)" + +[time] +disabled = false +time_format = "%R" +style = "bg:color_bg1" +format = "[[  $time ](fg:color_fg0 bg:color_bg1)]($style)" + +[line_break] +disabled = false + +[character] +disabled = false +success_symbol = "[](bold fg:color_green)" +error_symbol = "[](bold fg:color_red)" +vimcmd_symbol = "[](bold fg:color_green)" +vimcmd_replace_one_symbol = "[](bold fg:color_purple)" +vimcmd_replace_symbol = "[](bold fg:color_purple)" +vimcmd_visual_symbol = "[](bold fg:color_yellow)" diff --git a/modules/home/rsydn/shell/starship/starship.toml.bak b/modules/home/rsydn/shell/starship/starship.toml.bak new file mode 100644 index 0000000..371a8ca --- /dev/null +++ b/modules/home/rsydn/shell/starship/starship.toml.bak @@ -0,0 +1,181 @@ +"$schema" = "https://starship.rs/config-schema.json" + +format = """ +[](color_orange)\ +$os\ +$username\ +[](bg:color_yellow fg:color_orange)\ +$directory\ +[](fg:color_yellow bg:color_aqua)\ +$git_branch\ +$git_status\ +[](fg:color_aqua bg:color_blue)\ +$c\ +$cpp\ +$rust\ +$golang\ +$nodejs\ +$php\ +$java\ +$kotlin\ +$haskell\ +$python\ +[](fg:color_blue bg:color_bg3)\ +$docker_context\ +$conda\ +$pixi\ +[](fg:color_bg3 bg:color_bg1)\ +$time\ +[ ](fg:color_bg1)\ +$line_break$character""" + +palette = "gruvbox_dark" + +[palettes.gruvbox_dark] +color_fg0 = "#fbf1c7" +color_bg1 = "#3c3836" +color_bg3 = "#665c54" +color_blue = "#458588" +color_aqua = "#689d6a" +color_green = "#98971a" +color_orange = "#d65d0e" +color_purple = "#b16286" +color_red = "#cc241d" +color_yellow = "#d79921" + +[os] +disabled = false +style = "bg:color_orange fg:color_fg0" + +[os.symbols] +Windows = "󰍲" +Ubuntu = "󰕈" +SUSE = "" +Raspbian = "󰐿" +Mint = "󰣭" +Macos = "󰀵" +Manjaro = "" +Linux = "󰌽" +Gentoo = "󰣨" +Fedora = "󰣛" +Alpine = "" +Amazon = "" +Android = "" +AOSC = "" +Arch = "󰣇" +Artix = "󰣇" +EndeavourOS = "" +CentOS = "" +Debian = "󰣚" +Redhat = "󱄛" +RedHatEnterprise = "󱄛" +Pop = "" + +[username] +show_always = true +style_user = "bg:color_orange fg:color_fg0" +style_root = "bg:color_orange fg:color_fg0" +format = "[ $user ]($style)" + +[directory] +style = "fg:color_fg0 bg:color_yellow" +format = "[ $path ]($style)" +truncation_length = 3 +truncation_symbol = "…/" + +[directory.substitutions] +Documents = "󰈙 " +Downloads = " " +Music = "󰝚 " +Pictures = " " +Developer = "󰲋 " + +[git_branch] +symbol = "" +style = "bg:color_aqua" +format = "[[ $symbol $branch ](fg:color_fg0 bg:color_aqua)]($style)" + +[git_status] +style = "bg:color_aqua" +format = "[[($all_status$ahead_behind )](fg:color_fg0 bg:color_aqua)]($style)" + +[nodejs] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[c] +symbol = " " +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[cpp] +symbol = " " +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[rust] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[golang] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[php] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[java] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[kotlin] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[haskell] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[python] +symbol = "" +style = "bg:color_blue" +format = "[[ $symbol( $version) ](fg:color_fg0 bg:color_blue)]($style)" + +[docker_context] +symbol = "" +style = "bg:color_bg3" +format = "[[ $symbol( $context) ](fg:#83a598 bg:color_bg3)]($style)" + +[conda] +style = "bg:color_bg3" +format = "[[ $symbol( $environment) ](fg:#83a598 bg:color_bg3)]($style)" + +[pixi] +style = "bg:color_bg3" +format = "[[ $symbol( $version)( $environment) ](fg:color_fg0 bg:color_bg3)]($style)" + +[time] +disabled = false +time_format = "%R" +style = "bg:color_bg1" +format = "[[  $time ](fg:color_fg0 bg:color_bg1)]($style)" + +[line_break] +disabled = false + +[character] +disabled = false +success_symbol = "[](bold fg:color_green)" +error_symbol = "[](bold fg:color_red)" +vimcmd_symbol = "[](bold fg:color_green)" +vimcmd_replace_one_symbol = "[](bold fg:color_purple)" +vimcmd_replace_symbol = "[](bold fg:color_purple)" +vimcmd_visual_symbol = "[](bold fg:color_yellow)" diff --git a/modules/home/rsydn/shell/tmux.nix b/modules/home/rsydn/shell/tmux.nix index d27e614..fc13357 100644 --- a/modules/home/rsydn/shell/tmux.nix +++ b/modules/home/rsydn/shell/tmux.nix @@ -1,4 +1,4 @@ -{ lib, pkgs, ... }: { +{ config, lib, pkgs, ... }: { programs.tmux = { enable = lib.mkDefault true; clock24 = true; @@ -18,19 +18,26 @@ ''; }]; extraConfig = '' + # Terminal configuration for proper colors and features + set-option -g default-terminal "screen-256color" + set-option -ga terminal-overrides ",*256col*:Tc" + set-option -g focus-events on set -s extended-keys on set -as terminal-features 'xterm-ghostty:extkeys' set-option -g status-style "bg=#282a36 fg=#f8f8f2" - set -g status-interval 5 - setw -g automatic-rename on - set -g renumber-windows on - bind r source-file ~/.tmux.conf \; display-message "tmux reloaded" - bind | split-window -h + set -g status-interval 5 + setw -g automatic-rename on + set -g renumber-windows on + bind r source-file ~/.tmux.conf \; display-message "tmux reloaded" + bind | split-window -h bind - split-window -v unbind '"' unbind % set -g display-panes-time 1500 bind k send-keys -R \; send-keys C-l \; clear-history + # Ensure tmux panes spawn login nu so Starship integration runs + set -g default-shell "${config.home.profileDirectory}/bin/nu" + set -g default-command "${config.home.profileDirectory}/bin/nu --login" ''; }; } diff --git a/modules/nixos/audio.nix b/modules/nixos/audio.nix new file mode 100644 index 0000000..f1093db --- /dev/null +++ b/modules/nixos/audio.nix @@ -0,0 +1,13 @@ +{ lib, ... }: { + # Modern audio stack - PipeWire replaces PulseAudio + JACK + ALSA + services.pipewire = { + enable = lib.mkDefault true; + alsa.enable = lib.mkDefault true; + alsa.support32Bit = lib.mkDefault true; # For 32-bit games/apps + pulse.enable = lib.mkDefault true; # PulseAudio compatibility + jack.enable = lib.mkDefault true; # JACK compatibility + }; + + # Real-time audio priority + security.rtkit.enable = lib.mkDefault true; +} diff --git a/modules/nixos/bluetooth.nix b/modules/nixos/bluetooth.nix new file mode 100644 index 0000000..e3040b4 --- /dev/null +++ b/modules/nixos/bluetooth.nix @@ -0,0 +1,12 @@ +{ lib, ... }: { + hardware.bluetooth = { + enable = lib.mkDefault false; # Enable when needed + powerOnBoot = lib.mkDefault true; + settings = { + General = { + Enable = "Source,Sink,Media,Socket"; + Experimental = true; # Better codec support + }; + }; + }; +} diff --git a/modules/nixos/containerization.nix b/modules/nixos/containerization.nix index 909268e..1dcae25 100644 --- a/modules/nixos/containerization.nix +++ b/modules/nixos/containerization.nix @@ -1,15 +1,46 @@ -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, user, ... }: let - inherit (lib) mkEnableOption mkOption mkIf types mkMerge mkAfter optionals; + inherit (lib) + mkEnableOption mkOption mkIf types mkMerge mkAfter optionals mkDefault; cfg = config.rsydn.containerization; in { options.rsydn.containerization = { - docker = { + podman = { enable = mkOption { type = types.bool; default = true; description = - "Enable the Docker daemon with sane defaults for development."; + "Enable Podman for rootless containers as the primary engine."; + }; + + dockerCompat = mkOption { + type = types.bool; + default = true; + description = + "Expose the Docker-compatible socket for CLI compatibility."; + }; + + enableDnsnamePlugin = mkOption { + type = types.bool; + default = true; + description = + "Enable the dnsname CNI plugin so containers can resolve each other."; + }; + + extraPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ podman-compose podman-tui ]; + description = + "Additional Podman-related packages to install system-wide."; + }; + }; + + docker = { + enable = mkOption { + type = types.bool; + default = false; + description = + "Enable the Docker daemon alongside Podman when explicitly requested."; }; autoPrune = mkOption { @@ -58,6 +89,27 @@ in { }; config = mkMerge [ + (mkIf cfg.podman.enable { + virtualisation.podman = { + enable = true; + dockerCompat = cfg.podman.dockerCompat; + defaultNetwork.settings.dnsname.enable = cfg.podman.enableDnsnamePlugin; + }; + + environment.systemPackages = mkAfter cfg.podman.extraPackages; + + users.users.${user} = { + subUidRanges = mkDefault [{ + startUid = 100000; + count = 65536; + }]; + subGidRanges = mkDefault [{ + startGid = 100000; + count = 65536; + }]; + }; + }) + (mkIf cfg.docker.enable { virtualisation.docker = { enable = true; diff --git a/modules/nixos/desktops/README.md b/modules/nixos/desktops/README.md new file mode 100644 index 0000000..b83bbc8 --- /dev/null +++ b/modules/nixos/desktops/README.md @@ -0,0 +1,176 @@ +# Desktop Environments + +This directory contains system-level desktop environment configurations for NixOS desktop hosts. + +## Structure + +``` +desktops/ +├── base.nix # Shared desktop settings (XDG portals, polkit, gvfs) +├── plasma.nix # KDE Plasma 6 + SDDM +├── hyprland/ # Hyprland tiling compositor +│ └── default.nix +├── gaming.nix # Steam, Proton, GameMode, gaming tools +├── apps/ # Desktop applications +│ ├── browsers.nix # Brave, Zen Browser +│ └── terminals.nix # Alacritty (Dracula theme) +├── themes/ # Theme configurations +│ ├── catppuccin.nix # Catppuccin GTK/Qt theme +│ └── default.nix # Adwaita default theme +└── hardware-configuration.nix # Hardware-specific settings (generated) +``` + +## Available Desktop Environments + +### KDE Plasma 6 (`plasma.nix`) +- Full-featured desktop with SDDM display manager +- Wayland-first with X11 fallback +- Includes essential KDE applications (commented out by default) +- User-level Plasma configuration via Home Manager (optional) + +### Hyprland (`hyprland/default.nix`) +- Dynamic tiling Wayland compositor +- Minimal default keybinds (SUPER key) +- Includes Wayland utilities: wl-clipboard, grim, slurp +- User-level configuration for keybinds, visual settings + +## Additional Modules + +### Gaming (`gaming.nix`) +**Features:** +- Steam with Proton GE compatibility +- GameMode for performance optimization +- 32-bit graphics support for games +- Wine, Winetricks, Lutris, Heroic launcher +- MangoHud for FPS overlay +- Discord for communication +- Increased inotify watchers for modding tools + +### Apps (`apps/`) +**Browsers** (`browsers.nix`): +- Brave, Zen Browser (enabled by default) + +**Terminals** (`terminals.nix`): +- Alacritty enabled with JetBrains Mono + Dracula theme +- Kitty and WezTerm explicitly disabled to keep a single default + +### Themes (`themes/`) +**Catppuccin** (`catppuccin.nix`): +- Soothing pastel theme for GTK and Qt +- Mocha variant with blue accents +- Kvantum Qt theme engine +- Papirus icon theme +- Catppuccin cursor theme + +**Default** (`default.nix`): +- Adwaita theme (GNOME default) +- Minimal theming setup + +## Usage + +### Single Desktop Environment + +Import one desktop environment in your host configuration: + +```nix +# modules/nixos/hosts/your-host.nix +{ + imports = [ + ../desktops/plasma.nix + # OR + # ../desktops/hyprland + ]; +} +``` + +### Multi-Desktop Setup (Switch at Login) + +The current desktop host uses both KDE Plasma (for gaming) and Hyprland (for development): + +```nix +# modules/nixos/hosts/desktop.nix +{ + imports = [ + # Hardware + ../desktops/hardware-configuration.nix + + # Desktop Environments + ../desktops/plasma.nix # KDE Plasma (for gaming) + ../desktops/hyprland # Hyprland (for development) + + # Desktop Apps & Theme + ../desktops/apps/browsers.nix + ../desktops/apps/terminals.nix + ../desktops/themes/catppuccin.nix + + # Gaming & Features + ../desktops/gaming.nix + ../bluetooth.nix + ]; + + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + kernelPackages = pkgs.linuxPackages_cachyos-lts; + }; + + networking.hostName = "desktop"; + system.stateVersion = "24.05"; +} +``` + +**Boot Configuration:** +- CachyOS LTS kernel for gaming performance +- Systemd-boot for EFI boot management + +**Switch Desktop at Login:** +- SDDM login screen shows both Plasma and Hyprland sessions +- Select desired environment before logging in + +## Base Desktop Settings (`base.nix`) + +Shared settings imported by all desktop environments: + +- **XDG Portals**: Desktop integration, file picker, screen sharing +- **PolicyKit**: Privilege escalation for GUI apps +- **GVFS**: Trash, mounting, network drives +- **Common Packages**: pavucontrol, networkmanagerapplet + +## Adding a New Desktop Environment + +1. Create a new file (e.g., `gnome.nix`) +2. Import `./base.nix` for shared settings +3. Enable the desktop environment and display manager +4. Add essential system packages +5. Configure user-level settings via Home Manager + +Example: + +```nix +{ lib, pkgs, user, ... }: { + imports = [ ./base.nix ]; + + services.xserver = { + enable = true; + desktopManager.gnome.enable = true; + displayManager.gdm.enable = true; + }; + + environment.systemPackages = with pkgs; [ + gnome-tweaks + ]; +} +``` + +## Testing Desktop Changes + +```bash +# Dry-run to check closure +nix build .#nixosConfigurations.desktop.config.system.build.toplevel --dry-run + +# Build and switch +sudo nixos-rebuild switch --flake .#desktop + +# Format before committing +nix fmt +``` diff --git a/modules/nixos/desktops/apps/browsers.nix b/modules/nixos/desktops/apps/browsers.nix new file mode 100644 index 0000000..c61d233 --- /dev/null +++ b/modules/nixos/desktops/apps/browsers.nix @@ -0,0 +1,8 @@ +{ pkgs, user, ... }: { + # Browser configurations for desktop users + + home-manager.users.${user} = { + # User packages: Browsers + home.packages = with pkgs; [ brave ]; + }; +} diff --git a/modules/nixos/desktops/apps/terminals.nix b/modules/nixos/desktops/apps/terminals.nix new file mode 100644 index 0000000..1120694 --- /dev/null +++ b/modules/nixos/desktops/apps/terminals.nix @@ -0,0 +1,114 @@ +{ lib, pkgs, user, ... }: { + # Terminal emulator configurations for desktop users + + home-manager.users.${user} = { + # Provide JetBrains Mono font locally for Alacritty. + home.packages = with pkgs; [ jetbrains-mono ]; + + # Ensure Kitty stays disabled when desktop module is imported. + programs.kitty.enable = lib.mkForce false; + + # Configure Alacritty as the default terminal with Dracula theme. + programs.alacritty = { + enable = true; + settings = { + window.opacity = 0.85; + + font = { + normal = { + family = "JetBrains Mono"; + style = "Regular"; + }; + bold = { + family = "JetBrains Mono"; + style = "Bold"; + }; + italic = { + family = "JetBrains Mono"; + style = "Italic"; + }; + bold_italic = { + family = "JetBrains Mono"; + style = "Bold Italic"; + }; + size = 12.0; + }; + + colors = { + primary = { + background = "#282a36"; + foreground = "#f8f8f2"; + bright_foreground = "#ffffff"; + }; + + cursor = { + text = "#282a36"; + cursor = "#f8f8f2"; + }; + + vi_mode_cursor = { + text = "CellBackground"; + cursor = "CellForeground"; + }; + + selection = { + text = "CellForeground"; + background = "#44475a"; + }; + + normal = { + black = "#21222c"; + red = "#ff5555"; + green = "#50fa7b"; + yellow = "#f1fa8c"; + blue = "#bd93f9"; + magenta = "#ff79c6"; + cyan = "#8be9fd"; + white = "#f8f8f2"; + }; + + bright = { + black = "#6272a4"; + red = "#ff6e6e"; + green = "#69ff94"; + yellow = "#ffffa5"; + blue = "#d6acff"; + magenta = "#ff92df"; + cyan = "#a4ffff"; + white = "#ffffff"; + }; + + search = { + matches = { + foreground = "#44475a"; + background = "#50fa7b"; + }; + focused_match = { + foreground = "#44475a"; + background = "#ffb86c"; + }; + }; + + footer_bar = { + background = "#282a36"; + foreground = "#f8f8f2"; + }; + + hints = { + start = { + foreground = "#282a36"; + background = "#f1fa8c"; + }; + end = { + foreground = "#f1fa8c"; + background = "#282a36"; + }; + }; + }; + }; + }; + + # Keep WezTerm disabled to avoid conflicting terminal defaults. + programs.wezterm.enable = lib.mkForce false; + }; +} diff --git a/modules/nixos/desktops/base.nix b/modules/nixos/desktops/base.nix new file mode 100644 index 0000000..7e078bb --- /dev/null +++ b/modules/nixos/desktops/base.nix @@ -0,0 +1,27 @@ +{ lib, pkgs, ... }: { + # Shared desktop settings (imported by all DEs) + + # XDG portals for desktop integration + xdg.portal = { + enable = lib.mkDefault true; + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + }; + + # Policy kit for privilege escalation + security.polkit.enable = lib.mkDefault true; + + # GVFS for trash, mounting, etc + services.gvfs.enable = lib.mkDefault true; + + # Common desktop packages + environment.systemPackages = with pkgs; [ + # File managers (choose one) + # nautilus # GNOME + # dolphin # KDE + # thunar # XFCE + + # Basic utilities + pavucontrol # Audio control + networkmanagerapplet # Network management GUI + ]; +} diff --git a/modules/nixos/desktops/gaming.nix b/modules/nixos/desktops/gaming.nix new file mode 100644 index 0000000..dc9ec24 --- /dev/null +++ b/modules/nixos/desktops/gaming.nix @@ -0,0 +1,76 @@ +{ pkgs, ... }: { + # Gaming configuration module + # Steam, Proton, Vulkan, Wine, and gaming optimizations + + # Steam with Proton support + programs.steam = { + enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + + # Enable Proton compatibility layer + extraCompatPackages = with pkgs; + [ + proton-ge-bin # GloriousEggroll's Proton builds + ]; + }; + + # GameMode for performance optimization + programs.gamemode = { + enable = true; + settings = { + general = { renice = 10; }; + custom = { + start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'"; + end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'"; + }; + }; + }; + + # Enable 32-bit graphics support for games + hardware.graphics = { + enable = true; + enable32Bit = true; + }; + + # Gaming-related packages + environment.systemPackages = with pkgs; [ + # Game launchers + lutris + heroic # Epic Games, GOG launcher + # bottles # Windows app manager + + # Wine for Windows games + wineWowPackages.stable # Both 32 and 64-bit Wine + winetricks + + # Performance monitoring + mangohud # FPS overlay and performance metrics + # gamescope # Gaming compositor/micro-compositor + + # Proton utilities + # protonup-qt # Manage Proton versions + protontricks # Winetricks for Proton games + + # Communication + discord + # teamspeak_client + + # Other gaming tools + # steam-run # Run non-Steam games in Steam runtime + ]; + + # Vulkan support + environment.variables = { + # Enable Vulkan validation layers for debugging (optional) + # VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"; + }; + + # Kernel parameters for gaming performance (optional, adjust as needed) + # boot.kernelParams = [ + # "mitigations=off" # Disable CPU mitigations for performance (less secure) + # ]; + + # Increase file watchers for game modding tools + boot.kernel.sysctl = { "fs.inotify.max_user_watches" = 524288; }; +} diff --git a/modules/nixos/desktops/hardware-configuration.nix b/modules/nixos/desktops/hardware-configuration.nix new file mode 100644 index 0000000..1419afc --- /dev/null +++ b/modules/nixos/desktops/hardware-configuration.nix @@ -0,0 +1,78 @@ +# Hardware configuration for desktop +# Generated by running: nixos-generate-config --show-hardware-config +# This file contains hardware-specific settings that should be adjusted for your actual hardware + +{ config, lib, modulesPath, ... }: + +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + # Kernel modules needed during boot + # Adjust based on your hardware (NVMe, SATA, USB, etc.) + boot.initrd.availableKernelModules = + [ "nvme" "xhci_pci" "ahci" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; # Change to "kvm-intel" for Intel CPUs + + # Filesystem configuration + # Run `lsblk -f` or `blkid` to get your actual device UUIDs + fileSystems."/" = { + device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-ROOT-UUID"; + fsType = "ext4"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-BOOT-UUID"; + fsType = "vfat"; + options = [ "fmask=0022" "dmask=0022" ]; + }; + + # Swap configuration (optional) + # Uncomment and adjust if you have a swap partition + # swapDevices = [ + # { device = "/dev/disk/by-uuid/REPLACE-WITH-YOUR-SWAP-UUID"; } + # ]; + + # CPU microcode updates + hardware.cpu.amd.updateMicrocode = + lib.mkDefault config.hardware.enableRedistributableFirmware; + # For Intel CPUs, use this instead: + # hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; + + # GPU configuration + # Uncomment the section that matches your GPU + + # NVIDIA GPU + # services.xserver.videoDrivers = [ "nvidia" ]; + # hardware.nvidia = { + # modesetting.enable = true; + # powerManagement.enable = false; + # powerManagement.finegrained = false; + # open = false; # Use proprietary driver + # nvidiaSettings = true; + # package = config.boot.kernelPackages.nvidiaPackages.stable; + # }; + + # AMD GPU + # services.xserver.videoDrivers = [ "amdgpu" ]; + # hardware.opengl = { + # enable = true; + # driSupport = true; + # driSupport32Bit = true; # For 32-bit games + # }; + + # Intel GPU + # services.xserver.videoDrivers = [ "modesetting" ]; + # hardware.opengl = { + # enable = true; + # extraPackages = with pkgs; [ + # intel-media-driver + # vaapiIntel + # vaapiVdpau + # libvdpau-va-gl + # ]; + # }; + + # Maximum number of open files + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/modules/nixos/desktops/hyprland/default.nix b/modules/nixos/desktops/hyprland/default.nix new file mode 100644 index 0000000..40bd0e6 --- /dev/null +++ b/modules/nixos/desktops/hyprland/default.nix @@ -0,0 +1,71 @@ +{ pkgs, lib, user, ... }: { + imports = [ ../base.nix ]; + + # System-level: Enable Hyprland + programs.hyprland = { + enable = lib.mkDefault true; + xwayland.enable = lib.mkDefault true; + }; + + # Wayland-specific portal + xdg.portal.wlr.enable = lib.mkDefault true; + + # System packages: Wayland essentials + environment.systemPackages = with pkgs; [ + # Wayland essentials + wayland + wl-clipboard + wlr-randr + + # Screenshot & screen recording + grim # Screenshot + slurp # Region selector + # wf-recorder # Screen recording (optional) + ]; + + # User-level: Hyprland configuration + home-manager.users.${user} = { + wayland.windowManager.hyprland = { + enable = lib.mkDefault true; + xwayland.enable = lib.mkDefault true; + + settings = { + # Minimal config - expand as needed + "$mod" = "SUPER"; + + # Example keybinds + bind = [ + "$mod, Return, exec, kitty" # Terminal + "$mod, Q, killactive" + "$mod, M, exit" + "$mod, F, fullscreen" + "$mod, Space, togglefloating" + + # Move focus + "$mod, h, movefocus, l" + "$mod, l, movefocus, r" + "$mod, k, movefocus, u" + "$mod, j, movefocus, d" + ]; + + # Visual settings + general = { + gaps_in = 5; + gaps_out = 10; + border_size = 2; + }; + + decoration = { rounding = 8; }; + }; + }; + + # User packages: Hyprland utilities + home.packages = with pkgs; + [ + # Uncomment as needed: + # wofi # Launcher + # waybar # Status bar + # dunst # Notifications + ]; + }; +} diff --git a/modules/nixos/desktops/plasma.nix b/modules/nixos/desktops/plasma.nix new file mode 100644 index 0000000..4872624 --- /dev/null +++ b/modules/nixos/desktops/plasma.nix @@ -0,0 +1,42 @@ +{ lib, pkgs, user, ... }: { + imports = [ ./base.nix ]; + + # System-level: KDE Plasma 6 + services.desktopManager.plasma6.enable = lib.mkDefault true; + + # SDDM display manager + services.displayManager.sddm = { + enable = lib.mkDefault true; + wayland.enable = lib.mkDefault true; + }; + + # System packages: KDE applications + environment.systemPackages = with pkgs; + [ + # KDE applications (uncomment as needed) + # kdePackages.kate # Text editor + # kdePackages.dolphin # File manager + # kdePackages.konsole # Terminal + # kdePackages.okular # Document viewer + # kdePackages.gwenview # Image viewer + # kdePackages.spectacle # Screenshot tool + ]; + + # User-level: KDE Plasma settings (optional) + home-manager.users.${user} = { + # KDE Plasma configuration via Home Manager (optional) + # programs.plasma = { + # enable = true; + # workspace = { + # theme = "breeze-dark"; + # colorScheme = "BreezeDark"; + # }; + # }; + + # User packages for KDE environment + home.packages = with pkgs; + [ + # Add user-specific apps here + ]; + }; +} diff --git a/modules/nixos/desktops/themes/catppuccin.nix b/modules/nixos/desktops/themes/catppuccin.nix new file mode 100644 index 0000000..74142ff --- /dev/null +++ b/modules/nixos/desktops/themes/catppuccin.nix @@ -0,0 +1,64 @@ +{ lib, pkgs, user, ... }: { + # Catppuccin theme configuration + # Soothing pastel theme for both GTK and Qt applications + # Works with KDE Plasma, Hyprland, and other desktop environments + + # System packages: Theme engines and Catppuccin themes + environment.systemPackages = with pkgs; [ + libsForQt5.qtstyleplugin-kvantum # Kvantum Qt theme engine + qt6Packages.qtstyleplugin-kvantum # Kvantum for Qt6 + catppuccin-kvantum # Catppuccin theme for Kvantum + catppuccin-cursors # Catppuccin cursor theme + ]; + + home-manager.users.${user} = { + # GTK theming - Catppuccin Mocha variant + gtk = { + enable = true; + theme = { + name = "Catppuccin-Mocha-Standard-Blue-Dark"; + package = pkgs.catppuccin-gtk.override { + accents = [ + "blue" + ]; # Options: blue, flamingo, green, lavender, maroon, mauve, peach, pink, red, rosewater, sapphire, sky, teal, yellow + size = "standard"; # Options: standard, compact + variant = "mocha"; # Options: latte, frappe, macchiato, mocha + }; + }; + + # GTK icon theme + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + }; + + # Qt theming - Catppuccin via Kvantum + qt = { + enable = true; + platformTheme.name = "kvantum"; + style.name = "kvantum"; + }; + + # Kvantum configuration + xdg.configFile."Kvantum/kvantum.kvconfig".text = '' + [General] + theme=Catppuccin-Mocha-Blue + ''; + + # Cursor theme + home.pointerCursor = { + name = "catppuccin-mocha-blue-cursors"; + package = pkgs.catppuccin-cursors.mochaBlue; + size = 24; + gtk.enable = true; + x11.enable = true; + }; + + # XDG user directories for desktop environments + xdg.userDirs = { + enable = true; + createDirectories = true; + }; + }; +} diff --git a/modules/nixos/desktops/themes/default.nix b/modules/nixos/desktops/themes/default.nix new file mode 100644 index 0000000..649143d --- /dev/null +++ b/modules/nixos/desktops/themes/default.nix @@ -0,0 +1,33 @@ +{ lib, pkgs, user, ... }: { + # Default theme configuration for desktop + # Simple Adwaita-dark theme that works across all desktop environments + # Switch to catppuccin.nix or create your own for custom themes + + home-manager.users.${user} = { + # GTK theming - Adwaita Dark + gtk = { + enable = lib.mkDefault true; + theme = lib.mkDefault { + name = "Adwaita-dark"; + package = pkgs.gnome-themes-extra; + }; + iconTheme = lib.mkDefault { + name = "Adwaita"; + package = pkgs.adwaita-icon-theme; + }; + }; + + # Qt theming - Use GTK theme for consistency + qt = { + enable = lib.mkDefault true; + platformTheme.name = lib.mkDefault "gtk"; + style.name = lib.mkDefault "adwaita-dark"; + }; + + # XDG user directories for desktop environments + xdg.userDirs = { + enable = true; + createDirectories = true; + }; + }; +} diff --git a/modules/nixos/fonts.nix b/modules/nixos/fonts.nix new file mode 100644 index 0000000..c56813b --- /dev/null +++ b/modules/nixos/fonts.nix @@ -0,0 +1,30 @@ +{ lib, pkgs, ... }: { + fonts = { + enableDefaultPackages = lib.mkDefault true; + + packages = with pkgs; [ + # Nerd Fonts for terminal icons + (nerdfonts.override { fonts = [ "FiraCode" "JetBrainsMono" "Iosevka" ]; }) + + # Core fonts + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + liberation_ttf + + # Code fonts + fira-code + jetbrains-mono + ]; + + fontconfig = { + enable = lib.mkDefault true; + defaultFonts = { + monospace = [ "JetBrains Mono" "FiraCode Nerd Font" ]; + sansSerif = [ "Noto Sans" ]; + serif = [ "Noto Serif" ]; + emoji = [ "Noto Color Emoji" ]; + }; + }; + }; +} diff --git a/modules/nixos/graphics.nix b/modules/nixos/graphics.nix new file mode 100644 index 0000000..07d18a5 --- /dev/null +++ b/modules/nixos/graphics.nix @@ -0,0 +1,21 @@ +{ lib, pkgs, ... }: { + # Hardware acceleration (OpenGL/Vulkan) + hardware.graphics = { + enable = lib.mkDefault true; + enable32Bit = lib.mkDefault true; # For 32-bit games/apps + + extraPackages = with pkgs; [ + # Common drivers (expand based on your hardware) + mesa.drivers + vulkan-validation-layers + vulkan-tools + + # Intel-specific (comment out if not using Intel) + intel-media-driver + intel-vaapi-driver + + # AMD-specific (comment out if not using AMD) + # rocmPackages.clr.icd + ]; + }; +} diff --git a/modules/nixos/home/default.nix b/modules/nixos/home/default.nix index 867d3dc..f86c89c 100644 --- a/modules/nixos/home/default.nix +++ b/modules/nixos/home/default.nix @@ -1,3 +1,18 @@ { config, pkgs, lib, ... }: { - imports = [ ../../home/rsydn/base.nix ../../home/rsydn/shell/fish.nix ]; + # Minimal CLI-only Home Manager configuration + # Used for servers, VMs, and headless systems + # Desktop configs are handled directly in nixos/desktops/* modules + + imports = [ + ../../home/rsydn/base.nix # Base CLI tools (git, tmux, etc.) + ../../home/rsydn/shell/fish.nix # Shell configuration + ../../home/rsydn/shell/nushell.nix # Secondary Nushell setup + ]; + + config.programs.tmux.extraConfig = lib.mkAfter '' + # Prefer fish for interactive sessions; launch Nushell on demand. + set -g default-shell "${config.home.profileDirectory}/bin/fish" + set -g default-command "${config.home.profileDirectory}/bin/fish --login" + bind-key C-n new-window -n nushell "${config.home.profileDirectory}/bin/nu --login" + ''; } diff --git a/modules/nixos/hosts/desktop.nix b/modules/nixos/hosts/desktop.nix new file mode 100644 index 0000000..7bf3144 --- /dev/null +++ b/modules/nixos/hosts/desktop.nix @@ -0,0 +1,48 @@ +{ lib, pkgs, ... }: +let + hardwareConfigPath = builtins.toString ./. + + "/../desktops/hardware-configuration.nix"; + hardwareModule = if builtins.pathExists hardwareConfigPath then + import hardwareConfigPath + else + (_: { }); +in { + # Unified desktop configuration for gaming and development + # Includes both KDE Plasma and Hyprland - switch at login screen + + # Import hardware and desktop configurations + imports = [ + # Hardware + hardwareModule + + # Audio & Graphics + ../audio.nix + ../graphics.nix + + # Desktop Environments + ../desktops/plasma.nix # KDE Plasma (for gaming) + ../desktops/hyprland # Hyprland (for development) + + # Desktop Apps & Theme + ../desktops/apps/browsers.nix + ../desktops/apps/terminals.nix + ../desktops/themes/catppuccin.nix # Or use themes/default.nix for Adwaita + + # Gaming & Features + ../desktops/gaming.nix + ../bluetooth.nix + ]; + + # Boot configuration with CachyOS LTS kernel + boot = { + loader.systemd-boot.enable = true; + loader.efi.canTouchEfiVariables = true; + kernelPackages = pkgs.linuxPackages_cachyos-lts; + }; + + # Hostname + networking.hostName = "desktop"; + + # This value determines the NixOS release compatibility + system.stateVersion = "24.05"; +} diff --git a/modules/nixos/hosts/dev-vm.nix b/modules/nixos/hosts/dev-vm.nix index 7576d7e..3f43c2c 100644 --- a/modules/nixos/hosts/dev-vm.nix +++ b/modules/nixos/hosts/dev-vm.nix @@ -14,6 +14,7 @@ }; environment.systemPackages = with pkgs; [ + # Core utilities coreutils ast-grep ripgrep @@ -21,12 +22,30 @@ tree zip unzip - htop jq psmisc # provides killall and friends gh tree-sitter + + # System monitoring & debugging tools + htop # Process viewer + iotop # I/O monitoring + lsof # List open files + strace # System call tracing + ltrace # Library call tracing + gdb # GNU debugger + tcpdump # Network packet analyzer + ncdu # Disk usage analyzer ]; + services.qemuGuest.enable = true; + + services.openssh.openFirewall = false; + + networking.firewall = { + allowedTCPPorts = [ ]; + interfaces."tailscale0".allowedTCPPorts = [ 22 ]; + }; + imports = [ ../virtualization.nix ]; } diff --git a/modules/nixos/system.nix b/modules/nixos/system.nix index 217695e..6065365 100644 --- a/modules/nixos/system.nix +++ b/modules/nixos/system.nix @@ -1,8 +1,10 @@ -{ lib, ... }: { +{ lib, user, ... }: { imports = [ ./users.nix ./network.nix ./ssh.nix ./containerization.nix ]; nix = { settings.auto-optimise-store = lib.mkDefault true; + settings.experimental-features = lib.mkDefault [ "nix-command" "flakes" ]; + settings.trusted-users = lib.mkDefault [ "root" user ]; optimise.automatic = lib.mkDefault true; gc = { automatic = lib.mkDefault true;