From 6a513027993f080801b38afa5943adeafd5032af Mon Sep 17 00:00:00 2001 From: Morten Olsen Date: Mon, 15 Dec 2025 21:58:07 +0100 Subject: [PATCH] improvements --- docs/migration-analysis.md | 486 ------------------------------------ hosts/personal/default.nix | 106 +++++++- hosts/work/default.nix | 106 +++++++- modules/darwin/homebrew.nix | 9 +- modules/home/apps.nix | 2 +- modules/home/packages.nix | 5 + modules/home/shell.nix | 126 +++++++++- 7 files changed, 335 insertions(+), 505 deletions(-) delete mode 100644 docs/migration-analysis.md diff --git a/docs/migration-analysis.md b/docs/migration-analysis.md deleted file mode 100644 index cab4695..0000000 --- a/docs/migration-analysis.md +++ /dev/null @@ -1,486 +0,0 @@ -# Chezmoi to Nix Home Manager Migration Analysis - -## Executive Summary - -This document analyzes the current chezmoi-based dotfiles configuration to prepare for migration to Nix Home Manager with flakes. The configuration manages a macOS development environment with two distinct profiles: **personal** and **work** (ZeroNorth). - ---- - -## 1. Managed Dotfiles Overview - -### 1.1 File Structure - -| Chezmoi Path | Target Path | Type | Templated | -|--------------|-------------|------|-----------| -| `dot_zshrc` | `~/.zshrc` | Shell config | No | -| `dot_tmux.conf` | `~/.tmux.conf` | Tmux config | No | -| `dot_gitconfig.tmpl` | `~/.gitconfig` | Git config | **Yes** | -| `dot_gitignore_global` | `~/.gitignore_global` | Git ignore | No | -| `dot_Brewfile.tmpl` | `~/.Brewfile` | Homebrew packages | **Yes** | -| `dot_aerospace.toml` | `~/.aerospace.toml` | Window manager | No | -| `dot_config/atuin/config.toml` | `~/.config/atuin/config.toml` | Shell history | No | -| `dot_shellrc/rc.d/*` | `~/.shellrc/rc.d/*` | Shell scripts | No | -| `dot_ssh/config` | `~/.ssh/config` | SSH config | No | -| `dot_ssh/config.d/*` | `~/.ssh/config.d/*` | SSH host configs | No | -| `dot_ssh/private_keys/*` | `~/.ssh/keys/*` | SSH public keys | **Partial** | -| `private_Library/...` | `~/Library/...` | App configs | No | -| `private_Projects/*` | `~/Projects/*` | Project configs | No | - -### 1.2 External Dependencies - -From [`.chezmoiexternal.toml`](.chezmoiexternal.toml:1): - -```toml -[".ssh/authorized_keys"] - type = "file" - url = "https://github.com/morten-olsen.keys" - refreshPeriod = "168h" -``` - -**Migration consideration:** This fetches SSH authorized keys from GitHub. In Nix, this could be handled by: -- A custom derivation that fetches the keys at build time -- A systemd service/launchd agent that periodically updates the file -- Manual management with `home.file` and periodic updates - ---- - -## 2. Personal vs Work Differentiation - -### 2.1 Template Variable: `.work` - -The configuration uses a boolean `.work` template variable to differentiate between personal and work environments. - -### 2.2 Conditional Logic Summary - -#### `.chezmoiignore` - File Exclusions - -From [`.chezmoiignore`](.chezmoiignore:2): - -| Condition | Ignored Files | -|-----------|---------------| -| `work = false` (Personal) | `Projects/private`, `Projects/zeronorth` | -| `work = true` (Work) | `Projects/.gitconfig` | - -**Interpretation:** -- **Personal machines:** Don't deploy work-related project configs -- **Work machines:** Don't deploy the personal Projects/.gitconfig, use project-specific ones instead - -#### `dot_Brewfile.tmpl` - Package Differences - -From [`dot_Brewfile.tmpl`](dot_Brewfile.tmpl:66): - -| Environment | Additional Packages | -|-------------|---------------------| -| Personal only (`work != true`) | `darktable`, `signal`, `proton-mail-bridge`, `proton-pass`, `protonvpn`, `steam` | -| Work | (none additional) | - -#### `dot_gitconfig.tmpl` - Git Configuration - -From [`dot_gitconfig.tmpl`](dot_gitconfig.tmpl:45): - -| Environment | Git Include Configuration | -|-------------|---------------------------| -| Personal (`work = false`) | Single includeIf for `~/Projects/` → `~/Projects/.gitconfig` | -| Work (`work = true`) | Two includeIfs: `~/Projects/private/` and `~/Projects/zeronorth/` with separate configs | - -#### `dot_ssh/private_keys/private_github-private.pub.tmpl` - SSH Keys - -From [`dot_ssh/private_keys/private_github-private.pub.tmpl`](dot_ssh/private_keys/private_github-private.pub.tmpl:1): - -| Environment | SSH Key | -|-------------|---------| -| Personal | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFaIAP/ZJ7+7jeR44e1yIJjfQAB6MN351LDKJAXVF62P` | -| Work | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILAzuPy7D/54GxMq9Zhz0CUjaDnEQ6RkQ/yqVYl7U55k` | - ---- - -## 3. Detailed Configuration Analysis - -### 3.1 Shell Configuration - -#### Zsh ([`dot_zshrc`](dot_zshrc:1)) - -- Sets `XDG_RUNTIME_DIR` and `LANG` -- Sources scripts from `~/.shellrc/rc.d/*.sh` and `~/.shellrc/zshrc.d/*.zsh` -- Configures GPG TTY for SSH sessions -- Displays ASCII art welcome banner -- Configures FZF with Catppuccin color scheme -- Initializes: `atuin`, `direnv`, `starship`, `zoxide`, `pyenv` -- Adds Rust/Cargo to PATH - -#### Shell RC Scripts - -| File | Purpose | -|------|---------| -| [`01-env.sh`](dot_shellrc/rc.d/01-env.sh:1) | PATH setup, aliases (ls→eza, cat→bat, grep→rg, diff→delta, less→bat) | -| [`01-nvim.sh`](dot_shellrc/rc.d/01-nvim.sh:1) | Sets EDITOR=nvim, alias vim=nvim | -| [`05-nvm.sh`](dot_shellrc/rc.d/05-nvm.sh:1) | NVM initialization | - -### 3.2 Git Configuration - -#### Global Config ([`dot_gitconfig.tmpl`](dot_gitconfig.tmpl:1)) - -- **Aliases:** graph, ll, st, cm, append, submodules, df, last, br, brr, undo, unstage -- **Core:** Uses delta as pager, disables hooks, references global gitignore -- **Pull:** Fast-forward only -- **Push:** Auto setup remote -- **LFS:** Configured -- **Difftool:** nvim diff - -#### Project-Specific Configs - -| Config | Email | Signing Key | URL Rewrites | -|--------|-------|-------------|--------------| -| [`Projects/.gitconfig`](private_Projects/dot_gitconfig:1) (Personal) | `fbtijfdq@void.black` | Personal key | github-private, gitea.olsen.cloud | -| [`Projects/private/.gitconfig`](private_Projects/private_private/dot_gitconfig:1) (Work) | `fbtijfdq@void.black` | Work key | github-private, gitea.olsen.cloud | -| [`Projects/zeronorth/.gitconfig`](private_Projects/private_zeronorth/dot_gitconfig:1) (Work) | `morten.olsen@zeronorth.com` | ZeroNorth key | github-zeronorth | - -### 3.3 SSH Configuration - -#### Main Config ([`dot_ssh/config`](dot_ssh/config:1)) - -- Includes colima SSH config -- Includes all files from `~/.ssh/config.d/` -- Global settings: ControlMaster, 1Password SSH agent, ForwardAgent - -#### Host Configurations - -| Host | Hostname | Port | Identity | -|------|----------|------|----------| -| [`github.com`](dot_ssh/config.d/github:1) | ssh.github.com | 443 | Default | -| [`github-private`](dot_ssh/config.d/git-private:1) | ssh.github.com | 443 | github-private.pub | -| [`github-zeronorth`](dot_ssh/config.d/git-zeronorth:1) | ssh.github.com | 443 | github-zeronorth.pub | -| [`gitea-ssh.olsen.cloud`](dot_ssh/config.d/git-private:8) | gitea-ssh.olsen.cloud | 2202 | github-private.pub | -| [`coder.*`](dot_ssh/config.d/git-coder:7) | (proxy) | - | Coder CLI | - -### 3.4 Tmux Configuration ([`dot_tmux.conf`](dot_tmux.conf:1)) - -- Mouse enabled -- 256-color terminal support -- Vim-style keybindings (hjkl navigation) -- TPM (Tmux Plugin Manager) with auto-install -- Plugins: tmux-power, tmux-yank, tmux-sensible -- Vim-tmux navigator integration -- Custom bindings for splits, copy mode, lazygit popup - -### 3.5 Aerospace Window Manager ([`dot_aerospace.toml`](dot_aerospace.toml:1)) - -- Starts at login -- Tiling layout with gaps -- QWERTY key mapping -- Workspace navigation (alt+1-6) -- Window movement (cmd+shift+hjkl) -- Service mode for layout management -- Floating layout for Elgato apps - -### 3.6 Application Configs - -#### Atuin ([`dot_config/atuin/config.toml`](dot_config/atuin/config.toml:1)) - -```toml -style = "compact" -keymap_mode = "vim-normal" -``` - -#### Jellyfin TUI ([`private_Library/private_Application Support/jellyfin-tui/private_config.yaml`](private_Library/private_Application Support/jellyfin-tui/private_config.yaml:1)) - -- Server: jellyfin.olsen.cloud -- Username: morten -- Password stored in separate file - -### 3.7 Environment Variables (Work) - -From [`Projects/zeronorth/.envrc`](private_Projects/private_zeronorth/dot_envrc:1): - -```bash -export NODE_AUTH_TOKEN="op://Employee/Github NPM Token/password" -export NPM_TOKEN="op://Employee/Github NPM Token/password" -export NPM_GITHUB_TOKEN="op://Employee/Github NPM Token/password" -export AWS_PROFILE=zntest -``` - -Uses 1Password CLI references for secrets. - ---- - -## 4. Homebrew Packages - -### 4.1 Taps - -- `coder/coder` -- `felixkratz/formulae` -- `fluxcd/tap` -- `nikitabobko/tap` -- `sst/tap` - -### 4.2 Formulae (All Environments) - -| Category | Packages | -|----------|----------| -| **Languages/Runtimes** | python@3.13, deno, rustup, pyenv, uv | -| **Shell Tools** | zsh, atuin, starship, fzf, zoxide, direnv | -| **File Utils** | bat, eza, fd, ripgrep, rsync, unzip | -| **Git** | git, gh, git-delta, jj | -| **Containers/K8s** | docker, docker-buildx, docker-compose, colima, kubernetes-cli, helm, helmfile, k9s, istioctl, flux | -| **Dev Tools** | neovim, tmux, jq, graphviz, terraform, ansible, sshpass | -| **Media** | ffmpeg | -| **Security** | gnupg | -| **Other** | curl, watch, coder, opencode, tree-sitter-cli | - -### 4.3 Casks (All Environments) - -- **Terminal:** ghostty -- **Productivity:** 1password, 1password-cli, raycast, obsidian -- **Development:** dbeaver-community, lens -- **Media:** jellyfin-media-player, ollama-app -- **Window Management:** aerospace -- **Networking:** localsend, mqtt-explorer -- **Home Automation:** home-assistant - -### 4.4 Casks (Personal Only) - -- darktable (photo editing) -- signal (messaging) -- proton-mail-bridge, proton-pass, protonvpn (Proton suite) -- steam (gaming) - ---- - -## 5. Recommended Nix Home Manager Structure - -### 5.1 Flake Structure - -``` -flake.nix -├── flake.lock -├── home/ -│ ├── default.nix # Common configuration -│ ├── personal.nix # Personal-specific config -│ ├── work.nix # Work-specific config -│ └── modules/ -│ ├── shell/ -│ │ ├── zsh.nix -│ │ ├── starship.nix -│ │ ├── atuin.nix -│ │ └── aliases.nix -│ ├── git/ -│ │ ├── default.nix -│ │ ├── personal.nix -│ │ └── work.nix -│ ├── ssh/ -│ │ ├── default.nix -│ │ └── hosts.nix -│ ├── tmux.nix -│ ├── aerospace.nix -│ ├── neovim.nix -│ └── packages.nix -└── docs/ - └── migration-analysis.md -``` - -### 5.2 Configuration Approach - -```nix -# flake.nix (simplified) -{ - inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; - home-manager = { - url = "github:nix-community/home-manager"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - # Darwin support for macOS - nix-darwin = { - url = "github:LnL7/nix-darwin"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - outputs = { self, nixpkgs, home-manager, nix-darwin, ... }: { - homeConfigurations = { - "personal" = home-manager.lib.homeManagerConfiguration { - # Personal machine config - modules = [ ./home/default.nix ./home/personal.nix ]; - }; - "work" = home-manager.lib.homeManagerConfiguration { - # Work machine config - modules = [ ./home/default.nix ./home/work.nix ]; - }; - }; - }; -} -``` - -### 5.3 Module Mapping - -| Chezmoi File | Nix Module | Home Manager Option | -|--------------|------------|---------------------| -| `dot_zshrc` | `shell/zsh.nix` | `programs.zsh` | -| `dot_tmux.conf` | `tmux.nix` | `programs.tmux` | -| `dot_gitconfig.tmpl` | `git/default.nix` | `programs.git` | -| `dot_gitignore_global` | `git/default.nix` | `programs.git.ignores` | -| `dot_Brewfile.tmpl` | `packages.nix` | `home.packages` + homebrew module | -| `dot_aerospace.toml` | `aerospace.nix` | `home.file` | -| `dot_config/atuin/*` | `shell/atuin.nix` | `programs.atuin` | -| `dot_ssh/*` | `ssh/default.nix` | `programs.ssh` | - ---- - -## 6. Migration Challenges and Considerations - -### 6.1 Homebrew Integration - -**Challenge:** Many casks are macOS-specific and not available in nixpkgs. - -**Solutions:** -1. Use `nix-darwin` with homebrew module for casks -2. Keep a minimal Brewfile for casks only -3. Use `home.packages` for CLI tools available in nixpkgs - -**Packages requiring Homebrew:** -- All casks (1password, ghostty, aerospace, etc.) -- Some taps (coder, flux, opencode) - -### 6.2 1Password SSH Agent Integration - -**Challenge:** SSH config references 1Password agent socket. - -**Solution:** Use conditional paths or environment-specific SSH config: -```nix -programs.ssh = { - extraConfig = '' - IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" - ''; -}; -``` - -### 6.3 Tmux Plugin Manager (TPM) - -**Challenge:** TPM auto-installs from git, which doesn't fit Nix's declarative model. - -**Solutions:** -1. Use `programs.tmux.plugins` with nixpkgs tmux plugins -2. Package custom plugins as Nix derivations -3. Keep TPM but manage it outside Nix (hybrid approach) - -### 6.4 NVM (Node Version Manager) - -**Challenge:** NVM is imperative and conflicts with Nix's approach. - -**Solutions:** -1. Use `programs.nodejs` with specific version -2. Use `nix-shell` or `direnv` with `use nix` for project-specific Node versions -3. Use `devenv` or `flake.nix` per-project - -### 6.5 External Key Fetching - -**Challenge:** `.chezmoiexternal.toml` fetches SSH keys from GitHub. - -**Solutions:** -1. Create a derivation that fetches at build time (keys become stale) -2. Use a launchd agent to periodically update -3. Manual management with documentation - -### 6.6 Private/Sensitive Files - -**Challenge:** Files prefixed with `private_` contain sensitive data. - -**Solutions:** -1. Use `sops-nix` for encrypted secrets -2. Use `agenix` for age-encrypted secrets -3. Keep sensitive files outside Nix, managed separately -4. Use 1Password CLI references (already used in `.envrc`) - -### 6.7 Project-Specific Git Configs - -**Challenge:** Multiple git configs for different project directories. - -**Solution:** Use `programs.git.includes`: -```nix -programs.git = { - includes = [ - { - condition = "gitdir:~/Projects/zeronorth/"; - path = "~/Projects/zeronorth/.gitconfig"; - } - ]; -}; -``` - -### 6.8 macOS-Specific Paths - -**Challenge:** Hardcoded paths like `/opt/homebrew/bin`, `/Applications/`. - -**Solution:** Use Nix variables and conditionals: -```nix -home.sessionPath = [ "/opt/homebrew/bin" "$HOME/.local/bin" ]; -``` - ---- - -## 7. Migration Phases - -### Phase 1: Foundation -1. Set up flake structure with nix-darwin and home-manager -2. Create base configuration with common packages -3. Implement personal/work profile switching - -### Phase 2: Shell Environment -1. Migrate zsh configuration -2. Set up starship, atuin, zoxide, direnv -3. Configure shell aliases and environment variables - -### Phase 3: Development Tools -1. Migrate git configuration with conditional includes -2. Set up SSH configuration -3. Configure tmux (decide on TPM approach) -4. Set up neovim (if managed by chezmoi elsewhere) - -### Phase 4: Applications -1. Configure aerospace (via home.file) -2. Set up application configs (atuin, jellyfin-tui) -3. Handle Homebrew casks via nix-darwin - -### Phase 5: Secrets and Sensitive Data -1. Implement sops-nix or agenix for secrets -2. Migrate SSH keys -3. Handle 1Password integrations - -### Phase 6: Testing and Validation -1. Test on personal machine -2. Test on work machine -3. Document any manual steps required - ---- - -## 8. Summary - -### Key Findings - -1. **Two distinct profiles:** Personal and Work, differentiated by `.work` boolean -2. **Template usage:** Limited to Brewfile, gitconfig, SSH keys, and ignore rules -3. **External dependencies:** SSH authorized keys fetched from GitHub -4. **macOS-centric:** Heavy use of Homebrew casks, 1Password, aerospace -5. **Secrets:** 1Password CLI references used for work environment - -### Recommended Approach - -1. **Use nix-darwin** for macOS system configuration and Homebrew cask management -2. **Use home-manager** for user-level dotfiles and packages -3. **Implement profiles** using Nix modules with `mkIf` conditionals -4. **Keep Homebrew** for casks that aren't available in nixpkgs -5. **Use sops-nix** for managing sensitive configuration -6. **Gradual migration** - start with shell and git, then expand - -### Files to Create - -``` -flake.nix # Main flake with darwin and home-manager -home/default.nix # Common home-manager config -home/personal.nix # Personal-specific settings -home/work.nix # Work-specific settings -home/modules/shell/zsh.nix # Zsh configuration -home/modules/git/default.nix # Git configuration -home/modules/ssh/default.nix # SSH configuration -home/modules/tmux.nix # Tmux configuration -home/modules/packages.nix # Package declarations \ No newline at end of file diff --git a/hosts/personal/default.nix b/hosts/personal/default.nix index 81d3988..c9fde21 100644 --- a/hosts/personal/default.nix +++ b/hosts/personal/default.nix @@ -28,8 +28,110 @@ # Allow unfree packages nixpkgs.config.allowUnfree = true; - # Set the primary user for this machine (required for homebrew and other user-specific options) - system.primaryUser = username; + system = { + primaryUser = username; + keyboard = { + enableKeyMapping = true; + remapCapsLockToControl = true; + }; + startup.chime = false; + + defaults = { + spaces.spans-displays = false; + loginwindow = { + GuestEnabled = false; + DisableConsoleAccess = true; + }; + + + dock = { + autohide = true; + autohide-delay = 0.0; + autohide-time-modifier = 0.0; + orientation = "bottom"; + dashboard-in-overlay = true; + largesize = 85; + tilesize = 50; + magnification = true; + launchanim = false; + mru-spaces = false; + show-recents = false; + show-process-indicators = false; + static-only = true; + }; + + finder = { + AppleShowAllExtensions = true; + AppleShowAllFiles = true; + CreateDesktop = false; + FXDefaultSearchScope = "SCcf"; # current folder + QuitMenuItem = true; + }; + + NSGlobalDomain = { + NSAutomaticSpellingCorrectionEnabled = false; + NSAutomaticCapitalizationEnabled = false; + NSAutomaticPeriodSubstitutionEnabled = false; + NSAutomaticDashSubstitutionEnabled = false; + NSAutomaticQuoteSubstitutionEnabled = false; + NSAutomaticWindowAnimationsEnabled = false; + NSDocumentSaveNewDocumentsToCloud = false; + ApplePressAndHoldEnabled = false; + + KeyRepeat = 2; + InitialKeyRepeat = 10; + # Enable subpixel font rendering on non-Apple LCDs + # Reference: https://github.com/kevinSuttle/macOS-Defaults/issues/17#issuecomment-266633501 + AppleFontSmoothing = 2; + # Finder: show all filename extensions + AppleShowAllExtensions = true; + }; + CustomUserPreferences = { + LaunchServices = { + # Whether to enable quarantine for downloaded applications + LSQuarantine = false; + }; + trackpad = { + Clicking = true; + TrackpadRightClick = true; + }; + "com.apple.systempreferences" = { + # Disable Resume system-wide + NSQuitAlwaysKeepsWindows = false; + }; + "com.apple.desktopservices" = { + # Avoid creating .DS_Store files on network or USB volumes + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + "com.apple.screensaver" = { + # Require password immediately after sleep or screen saver begins + askForPassword = 1; + askForPasswordDelay = 0; + }; + "com.apple.AdLib" = { + # Don't fucking track me... + allowApplePersonalizedAdvertising = false; + }; + "com.apple.BluetoothAudioAgent" = { + # Increase sound quality for Bluetooth headphones/headsets + "Apple Bitpool Min (editable)" = -40; + }; + "com.apple.dashboard" = { + # Disable Dashboard + mcx-disabled = true; + }; + alf = { + # Enables Firewall + globalstate = 1; + # Enable logging of requests + loggingenabled = 1; + # Drops incoming requests via ICMP such as ping requests + stealthenabled = 1; + }; + }; + }; + }; users.users.${username} = { name = username; diff --git a/hosts/work/default.nix b/hosts/work/default.nix index e5acfe9..fdcb1cd 100644 --- a/hosts/work/default.nix +++ b/hosts/work/default.nix @@ -28,8 +28,110 @@ # Allow unfree packages nixpkgs.config.allowUnfree = true; - # Set the primary user for this machine (required for homebrew and other user-specific options) - system.primaryUser = username; + system = { + primaryUser = username; + keyboard = { + enableKeyMapping = true; + remapCapsLockToControl = true; + }; + startup.chime = false; + + defaults = { + spaces.spans-displays = false; + loginwindow = { + GuestEnabled = false; + DisableConsoleAccess = true; + }; + + + dock = { + autohide = true; + autohide-delay = 0.0; + autohide-time-modifier = 0.0; + orientation = "bottom"; + dashboard-in-overlay = true; + largesize = 85; + tilesize = 50; + magnification = true; + launchanim = false; + mru-spaces = false; + show-recents = false; + show-process-indicators = false; + static-only = true; + }; + + finder = { + AppleShowAllExtensions = true; + AppleShowAllFiles = true; + CreateDesktop = false; + FXDefaultSearchScope = "SCcf"; # current folder + QuitMenuItem = true; + }; + + NSGlobalDomain = { + NSAutomaticSpellingCorrectionEnabled = false; + NSAutomaticCapitalizationEnabled = false; + NSAutomaticPeriodSubstitutionEnabled = false; + NSAutomaticDashSubstitutionEnabled = false; + NSAutomaticQuoteSubstitutionEnabled = false; + NSAutomaticWindowAnimationsEnabled = false; + NSDocumentSaveNewDocumentsToCloud = false; + ApplePressAndHoldEnabled = false; + + KeyRepeat = 2; + InitialKeyRepeat = 10; + # Enable subpixel font rendering on non-Apple LCDs + # Reference: https://github.com/kevinSuttle/macOS-Defaults/issues/17#issuecomment-266633501 + AppleFontSmoothing = 2; + # Finder: show all filename extensions + AppleShowAllExtensions = true; + }; + CustomUserPreferences = { + LaunchServices = { + # Whether to enable quarantine for downloaded applications + LSQuarantine = false; + }; + trackpad = { + Clicking = true; + TrackpadRightClick = true; + }; + "com.apple.systempreferences" = { + # Disable Resume system-wide + NSQuitAlwaysKeepsWindows = false; + }; + "com.apple.desktopservices" = { + # Avoid creating .DS_Store files on network or USB volumes + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + "com.apple.screensaver" = { + # Require password immediately after sleep or screen saver begins + askForPassword = 1; + askForPasswordDelay = 0; + }; + "com.apple.AdLib" = { + # Don't fucking track me... + allowApplePersonalizedAdvertising = false; + }; + "com.apple.BluetoothAudioAgent" = { + # Increase sound quality for Bluetooth headphones/headsets + "Apple Bitpool Min (editable)" = -40; + }; + "com.apple.dashboard" = { + # Disable Dashboard + mcx-disabled = true; + }; + alf = { + # Enables Firewall + globalstate = 1; + # Enable logging of requests + loggingenabled = 1; + # Drops incoming requests via ICMP such as ping requests + stealthenabled = 1; + }; + }; + }; + }; users.users.${username} = { name = username; diff --git a/modules/darwin/homebrew.nix b/modules/darwin/homebrew.nix index accba4b..c9f81a9 100644 --- a/modules/darwin/homebrew.nix +++ b/modules/darwin/homebrew.nix @@ -62,6 +62,9 @@ in { # Gaming "steam" + + # Web + "zen" ]; description = "Homebrew casks to install only on personal machines"; }; @@ -78,6 +81,8 @@ in { # Communication "slack" "pritunl" + "google-chrome" + "cursor" ]; description = "Homebrew casks to install only on work machines"; }; @@ -96,9 +101,9 @@ in { # These are from custom taps or preferred from Homebrew "coder/coder/coder" "fluxcd/tap/flux" - "nvm" "sst/tap/opencode" "tree-sitter-cli" + "borders" ]; description = "Homebrew formulae to install (for packages not in nixpkgs)"; }; @@ -158,6 +163,8 @@ in { # Formulae (CLI tools from Homebrew) brews = cfg.brews; + caskArgs.no_quarantine = true; + # Casks (GUI applications) casks = cfg.casks.shared diff --git a/modules/home/apps.nix b/modules/home/apps.nix index ce61124..846fc70 100644 --- a/modules/home/apps.nix +++ b/modules/home/apps.nix @@ -169,4 +169,4 @@ in { }) ]; }; -} \ No newline at end of file +} diff --git a/modules/home/packages.nix b/modules/home/packages.nix index e4e4427..aa020be 100644 --- a/modules/home/packages.nix +++ b/modules/home/packages.nix @@ -30,6 +30,7 @@ duf # A better df alternative hyperfine # A command-line benchmarking tool. choose # A human-friendly and fast alternative to cut and (sometimes) awk + yazi # File manager # ======================================================================== # File and Text Utilities @@ -65,6 +66,7 @@ python313 # Python 3.13 # pyenv is configured in shell.nix uv # Fast Python package installer + mise # tool manager # Build Tools gnumake # Make build tool @@ -117,6 +119,9 @@ tldr # Simplified man pages doggo # Command-line DNS client for humans. dig on steroids btop # A monitor of resources + gh + mob + zsh-fast-syntax-highlighting # ======================================================================== # Nix Tools diff --git a/modules/home/shell.nix b/modules/home/shell.nix index 33b346d..0563bf5 100644 --- a/modules/home/shell.nix +++ b/modules/home/shell.nix @@ -8,7 +8,6 @@ # - Zoxide for smart directory navigation # - Shell aliases from the chezmoi configuration # - Environment variables -# - NVM for Node.js version management { config, pkgs, @@ -40,6 +39,13 @@ share = true; }; + plugins = [ + { + name = "fast-syntax-highlighting"; + src = "${pkgs.zsh-fast-syntax-highlighting}/share/zsh/site-functions"; + } + ]; + # Session variables (migrated from dot_zshrc and 01-env.sh) sessionVariables = { # XDG runtime directory @@ -76,12 +82,26 @@ grep = "rg"; diff = "delta"; less = "bat"; + g = "git"; + k = "kubectl --all-namespaces"; + ssh = "TERM=screen ssh"; # Neovim alias (from 01-nvim.sh) vim = "nvim"; + vi = "nvim"; # Git root navigation (from 01-env.sh) gr = "if [ \"`git rev-parse --show-cdup`\" != \"\" ]; then cd `git rev-parse --show-cdup`; fi"; + + # Misc + psf = "ps -aux | grep"; + + # Docker + docloc = "docker run --rm -it -v `PWD`:/usr/workdir --workdir=/usr/workdir"; + + # Nix + nsh = "nix-shell"; + nse = "nix search nixpkgs"; }; # Additional initialization (initExtra) @@ -90,21 +110,23 @@ # Source custom env file if it exists [ -f ~/.env ] && source ~/.env - # NVM initialization - # Load NVM if installed via Homebrew - if [ -s "/opt/homebrew/opt/nvm/nvm.sh" ]; then - source "/opt/homebrew/opt/nvm/nvm.sh" - fi - # Load NVM bash completion - if [ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ]; then - source "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" - fi - # Pinentry configuration for SSH sessions if [[ -n "$SSH_CONNECTION" ]]; then export PINENTRY_USER_DATA="USE_CURSES=1" fi + function cd() { + builtin cd $* + ls + } + + function mkd() { + mkdir $1 + builtin cd $1 + } + + function take() { builtin cd $(mktemp -d) } + # Welcome banner (from dot_zshrc) # Only show if terminal is wide enough if [ `tput cols` -gt "70" ]; then @@ -162,8 +184,13 @@ programs.starship = { enable = true; enableZshIntegration = true; - # Starship configuration can be customized here - # settings = { }; + settings = { + add_newline = false; + character = { + success_symbol = "[λ](bold green)"; + error_symbol = "[λ](bold red)"; + }; + }; }; # ========================================================================== @@ -223,4 +250,77 @@ enable = true; enableZshIntegration = true; }; + + programs.pet = { + enable = true; + }; + + programs.mise = { + enable = true; + enableZshIntegration = true; + enableNushellIntegration = true; + settings = { + experimental = true; + verbose = false; + auto_install = true; + }; + }; + + home.activation.setupMise = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + # use the virtual environment created by uv + # ${pkgs.mise}/bin/mise settings set python.uv_venv_auto true + + # enable corepack (pnpm, yarn, etc.) + ${pkgs.mise}/bin/mise set MISE_NODE_COREPACK=true + + # disable warning about */.node-version files + ${pkgs.mise}/bin/mise settings add idiomatic_version_file_enable_tools "[]" + + # set global tool versions (auto_install will handle installation) + ${pkgs.mise}/bin/mise use --global node@lts + ${pkgs.mise}/bin/mise use --global bun@latest + ${pkgs.mise}/bin/mise use --global deno@latest + ${pkgs.mise}/bin/mise use --global uv@latest + ''; + + programs.nushell = { + enable = true; + # The config.nu can be anywhere you want if you like to edit your Nushell with Nu + # configFile.source = ./.../config.nu; + # for editing directly to config.nu + extraConfig = '' + let carapace_completer = {|spans| + carapace $spans.0 nushell ...$spans | from json + } + $env.config = { + show_banner: false, + completions: { + case_sensitive: false # case-sensitive completions + quick: true # set to false to prevent auto-selecting completions + partial: true # set to false to prevent partial filling of the prompt + algorithm: "fuzzy" # prefix or fuzzy + external: { + # set to false to prevent nushell looking into $env.PATH to find more suggestions + enable: true + # set to lower can improve completion performance at the cost of omitting some options + max_results: 100 + completer: $carapace_completer # check 'carapace_completer' + } + } + } + $env.PATH = ($env.PATH | + split row (char esep) | + append /usr/bin/env + ) + ''; + shellAliases = { + vi = "hx"; + vim = "hx"; + nano = "hx"; + }; + }; + programs.carapace = { + enable = true; + enableNushellIntegration = true; + }; }