This is a personal macOS dotfiles repository managed with chezmoi. The configuration includes a complete desktop environment with Yabai (tiling window manager), SketchyBar (status bar), Neovim, Fish shell, and various development tools.
This repository uses .chezmoiroot to specify a subdirectory as the source state root. The actual dotfiles are located in the home/ directory:
dotfiles/
├── .chezmoiroot # Contains "home" - specifies source root
├── home/ # Source state root (chezmoi manages this)
│ ├── .chezmoi.toml.tmpl
│ ├── .chezmoiscripts/
│ ├── .chezmoiexternals/
│ ├── dot_config/
│ ├── dot_bin/
│ └── ...
├── docs/ # Documentation (not managed by chezmoi)
├── assets/ # Images for documentation
└── ...
This structure allows keeping documentation, assets, and configuration files separate from the actual dotfiles that chezmoi manages.
Files and directories use chezmoi's naming conventions:
dot_prefix → becomes.(e.g.,dot_config→.config)private_prefix → files excluded from git and restricted permissions.tmplsuffix → files processed as templates with chezmoi variablesexecutable_prefix → files made executable
All paths below are relative to home/ (the chezmoi source root):
home/.chezmoiscripts/- Automated setup scripts that run after chezmoi apply- Scripts are ordered with prefixes like
run_once_after_1_,run_once_after_2_, etc. run_once_weekly_*scripts run periodically- All scripts are Fish shell scripts with
.fish.tmplextension
- Scripts are ordered with prefixes like
home/.chezmoiexternals/- External dependencies managed by chezmoifish.toml- Fish shell pluginsyazi.toml- Yazi file manager pluginsnvim.toml- Neovim external configurations
home/dot_config/- Application configurations (becomes~/.config/)home/dot_bin/- User scripts and utilitieshome/dot_claude/- Claude Code configuration (becomes~/.claude/)home/dot_mcp.json.tmpl- Centralized MCP servers configurationdocs/- Documentation (outside chezmoi root)assets/- Images and other static files for documentation
All paths below are relative to home/ (the chezmoi source root):
- Neovim (
dot_config/nvim/) - Uses LazyVimx configuration, supports stable and nightly versions - Fish Shell (
dot_config/fish/) - Comprehensive shell with custom functions, XDG compliance, theme switching - Zsh (
dot_config/zsh/) - Zsh shell configuration - Yabai (
dot_config/yabai/) - Tiling window manager written in Fish shell with automatic space creation and application assignment - SketchyBar (
dot_config/sketchybar/) - Status bar written in Lua with modular item system - skhd (
dot_config/skhd/) - Hotkey daemon for window management keybindings - SketchyVim (
dot_config/svim/) - System-wide Vim-like navigation with Russian keyboard layout support - Karabiner (
dot_config/private_karabiner/) - Keyboard customization and complex modifications - JankyBorders (
dot_config/borders/) - Visual window borders for Yabai - Git (
dot_config/git/) - Git configuration with KeePassXC integration for secrets - Yazi (
dot_config/yazi/) - File manager with Catppuccin theme and custom plugins - LazyGit (
dot_config/lazygit/) - Git TUI with dark/light theme support - WezTerm (
dot_config/wezterm/) - Terminal emulator configuration - Ghostty (
dot_config/ghostty/) - Fast terminal emulator with quick terminal, Display P3 colorspace, Catppuccin theme - Claude Code (
dot_claude/) - AI assistant configuration with MCP servers - Matterhorn (
dot_config/matterhorn/) - Terminal-based Mattermost client - Oh My Posh (
dot_config/oh-my-posh/) - Prompt theme engine - Raycast (
dot_bin/raycast/) - Script commands for productivity launcher- Tailscale VPN management (exit-node selection, status display)
- YouTube video download
- VM services restart (Yabai, skhd, SketchyBar, etc.)
- Application launchers
- See Raycast documentation for details
- Zed (
dot_config/zed/) - Code editor configuration - Bat (
dot_config/bat/) - Cat clone with syntax highlighting - Vim (
dot_config/vim/) - Vim configuration - Mise (
dot_config/mise/) - Development tool version manager (replaces asdf) - Asdf (
dot_config/asdf/) - Legacy version manager configuration - Homebrew (
dot_config/homebrew/) - macOS package manager configuration (Brewfile) - NPM (
dot_config/npm/) - Node package manager configuration - Stylus (
dot_config/stylus/) - Browser extension styles
# Apply changes from dotfiles repository
chezmoi apply
# Edit a file in the dotfiles repository
chezmoi edit ~/.config/fish/config.fish
# Re-run install scripts
chezmoi init --apply
# View what would change without applying
chezmoi diff
# Add a new file to chezmoi
chezmoi add ~/.config/newapp/config.toml# Install all packages (Homebrew + mise tools)
brew bundle install --file $XDG_CONFIG_HOME/homebrew/Brewfile
mise install -y
# Update mise tools
mise upgrade
# Update Homebrew packages
brew update && brew upgrade
# List installed mise tools
mise ls
# Install specific tool
mise use -g node@latest# Test script from command line
~/.bin/raycast/tailscale.sh enable
# Edit script in dotfiles
chezmoi edit ~/.bin/raycast/tailscale.sh
# Add new script to chezmoi
chezmoi add ~/.bin/raycast/new_script.shAll development tools are managed via mise (configured in dot_config/mise/config.toml):
Languages:
- Node.js (latest), Python (3.12), Ruby (latest), Go (latest), Rust (latest), Bun (latest)
- Neovim (both stable and nightly versions via custom asdf plugin)
Package Managers:
- pnpm (Node.js)
- pipx (Python)
- cargo (Rust)
Tool Installation Backends:
asdf:- Traditional asdf pluginscargo:- Rust packages (eza, yazi, bottom, tokei, vivid, genact)npm:- Node packages (Claude Code, Arc CLI, SketchyBar App Font)pipx:- Python CLI tools (httpie, neovim-remote)ubi:- Direct GitHub releases (ripgrep, fd, bat, fzf, lazygit, chezmoi, etc.)
Yabai & skhd keybindings:
Alt + 1-9,0,-,=- Switch to workspace 1-12Alt + h/j/k/l- Focus window (vim-like)Alt + Shift + h/j/k/l- Move windowAlt + Ctrl + arrows- Resize windowAlt + Shift + f- Toggle floatAlt + Shift + m- Toggle fullscreenAlt + Shift + e- Balance windows
SketchyBar:
# Reload SketchyBar
sketchybar --reload
# Trigger specific event
sketchybar --trigger window_focusServices:
# Start/stop Yabai
yabai --start-service
yabai --stop-service
# Start/stop skhd
skhd --start-service
skhd --stop-service
# Start/stop SketchyBar
brew services start sketchybar
brew services stop sketchybarThis repository uses commitlint with conventional commits. Valid scopes are defined in .commitlintrc.js:
- Component scopes:
asdf,bat,borders,brew,claude,chezmoi,fish,ghostty,git,gitconfig,karabiner,lazygit,mise,nvim,oh-my-posh,raycast,sketchybar,skhd,ssh,svim,termscp,them-switcher,time,vscode,wezterm,yabai,yazi,zed,zrok,zsh - Generic scopes:
other,shell,install-script
Commits must follow the format: type(scope): description
Example: feat(nvim): add new keybinding for LSP actions
Use npm run commit for interactive commit message creation.
Files with .tmpl extension are processed as Go templates. Common patterns:
Variables:
{{ .chezmoi.os }}- Operating system (typically "darwin"){{ .chezmoi.homeDir }}- User's home directory{{ .chezmoi.username }}- Current user{{ .chezmoi.hostname }}- Machine hostname
Conditional blocks:
{{ if (eq .chezmoi.os "darwin") -}}
# macOS-specific configuration
{{ end -}}KeePassXC integration for secrets:
{{ (keepassxcAttribute "entry-name" "attribute-name").Text }}The dot_config/mise/config.toml defines all development tools using TOML format:
Tool aliases (shorthand names):
[alias]
neovim = "asdf:richin13/asdf-neovim"Tool versions:
[tools]
node = "latest"
python = "3.12"
neovim = ["nightly", "stable"] # Multiple versions supportedBackend-specific tools:
asdf:- Traditional asdf plugins with repository pathcargo:- Rust crates from crates.ionpm:- Node packages with optional exe mappingpipx:- Python CLI applicationsubi:- GitHub releases with automatic binary detection
The entire environment supports automatic dark/light theme switching based on macOS system appearance:
Environment variable:
MACOS_IS_DARK- Set by system (true/false)
Components that auto-switch:
- Fish shell (Catppuccin Macchiato/Latte)
- Neovim (via LazyVimx)
- Yazi file manager
- LazyGit
- FZF (search tool)
- Bat (file viewer)
- Oh My Posh (prompt)
Implementation:
- Fish 4.3+ uses
fish_terminal_color_themevariable that automatically updates when modern terminals (Ghostty, iTerm2, WezTerm) send OSC sequences - The
reload_themefunction inconf.d/theme_setup.fishautomatically triggers onfish_terminal_color_themechanges - Theme-specific cache files stored separately
- Environment variables
MACOS_IS_DARKandCATPPUCCIN_FLAVORare set byreload_themefunction - Color schemes for fzf, bat, eza, and fish shell are reloaded automatically across all open sessions
SketchyBar is configured entirely in Lua with a modular structure:
Core files:
init.lua- Entry point, requires all modulesbar.lua- Bar appearance (position, height, colors)config.lua- Shared configuration (fonts, padding, colors)default.lua- Default item propertiesexecutable_sketchybarrc- Shell script that installs SbarLua and starts event loop
Item structure:
items/
├── init.lua # Requires all items
├── left/ # Left-aligned items
│ ├── spaces.lua # Yabai workspace indicators
│ └── yabai.lua # Window layout status
└── right/ # Right-aligned items
├── keyboard_layout.lua # Current input method
├── svim.lua # SketchyVim mode indicator
├── tailscale.lua # Tailscale VPN status
├── battery.lua # Battery status
└── datetime.lua # Date and time
Event system:
- Items subscribe to system events (window_focus, space_change, etc.)
- External triggers via
sketchybar --trigger event_name - Integration with Yabai signals for window management updates
Directory structure:
home/dot_config/fish/
├── config.fish.tmpl # Main config (template for secrets)
├── conf.d/ # Auto-loaded configs
│ └── recursive_paths.fish # Function/completion path setup
└── functions/ # Custom functions
└── core/ # Core functions
├── git/ # Git-related functions
├── yabai/ # Yabai helper functions
├── wrappers/ # Command wrappers
└── *.fish # Individual functions
Initialization order:
- Environment variables set in
~/.zshenv(loaded first, even for Fish) conf.d/scripts auto-loadedconfig.fish.tmplmain configuration- Functions loaded on-demand from
functions/
Key features:
- XDG Base Directory compliance
- Recursive function/completion path discovery
- Cached initializations for performance (Homebrew, mise, zoxide)
- Vi mode with custom keybindings
- Automatic theme switching
The Yabai configuration is written entirely in Fish shell (executable_yabairc), leveraging Fish's clean syntax and integration with other Fish functions.
Configuration flow:
- Load scripting addition (requires SIP disabled)
- Set up SketchyBar signals
- Configure global settings (layout, padding, gaps, mouse)
- Create/rename spaces dynamically using Fish functions
- Assign applications to specific spaces
- Set per-app layout exceptions
Helper functions (located in dot_config/fish/functions/core/yabai/):
yabai.rearrange.fish- Rearranges windows when new ones are createdyabai.restart.fish- Restarts Yabai serviceyabai.sudoers.fish- Manages sudoers configuration for scripting addition
Space management:
- Spaces created automatically on startup
- Custom names for workspaces (Code, Serf, Org, Graph, Explr, Fun, Sys, Ai, Any, Social, Calls, Media)
- Application-to-space assignments (including Claude, Zed, Perplexity, Cursor, Dia)
- Per-space layout rules
Integration points:
- skhd for keybindings
- SketchyBar for visual feedback (via signals)
- Fish functions for helper scripts
- Signal triggers
yabai.rearrangeon window creation
Located in dot_config/git/config.tmpl:
- Secrets loaded from KeePassXC via chezmoi templates (user name, email, GPG signing key)
- GPG commit signing enabled by default
- Custom pager:
diff-so-fancywith color configuration - Custom diff tool:
difftastic - Custom merge tool: Neovim with DiffviewOpen
- Git aliases:
lg- Pretty graph log with colorsdlog- Log with difftastic external diffdft- Shortcut for difftool
First boot setup (documented in README.md):
- Install Xcode Command Line Tools:
xcode-select --install - Install Homebrew
- Install mise and fish:
brew install mise fish - Install KeePassXC:
brew install --cask keepassxc - Install chezmoi via mise:
mise install ubi:twpayne/chezmoi - Initialize dotfiles:
$(mise where ubi:twpayne/chezmoi)/bin/chezmoi init --apply aimuzov
The chezmoi scripts in .chezmoiscripts/ automatically handle:
run_once_after_1_install-packages.fish.tmpl- Install Homebrew packages and mise toolsrun_once_after_2_configure-system.fish.tmpl- Configure macOS system settingsrun_once_after_3_setup-theme-switcher.fish.tmpl- Set up automatic theme switchingrun_once_after_4_setup-sketchybar.fish.tmpl- Configure SketchyBarrun_once_after_5_install-workflows.fish.tmpl- Install custom workflowsrun_once_after_7_download-cht.fish.tmpl- Download cheatsheetsrun_once_weekly_1_rebuild_cache.fish.tmpl- Rebuild caches weekly
- Check if Accessibility permissions are granted
- Verify scripting addition is loaded:
yabai -m query --windows - If using scripting addition, ensure SIP is disabled (see Yabai wiki)
- Ensure SbarLua is installed:
brew install FelixKratz/formulae/sbarlua - Check service status:
brew services list | grep sketchybar - Reload manually:
sketchybar --reload
- Verify
~/.zshenvsetsSHELLand sources mise - Check XDG directories exist:
echo $XDG_CONFIG_HOME - Test config:
fish --debug
- Ensure mise is activated in shell:
mise doctor - Check PATH includes mise shims:
echo $PATH | grep mise - Reinstall tools:
mise install -y
- Verify
MACOS_IS_DARKenvironment variable:echo $MACOS_IS_DARK - Check Fish terminal color theme:
echo $fish_terminal_color_theme - Verify your terminal supports OSC sequences (Ghostty, iTerm2, WezTerm do)
- Manually reload theme:
theme_reload(ortrshortcut) - Check if
reload_themefunction exists:type reload_theme - Restart Fish shell if automatic detection fails
- Add to
home/dot_config/mise/config.tomlunder appropriate backend - Run
mise installto install - Commit changes with scope
mise
- Add file to appropriate
home/dot_config/subdirectory - Use chezmoi naming conventions (
dot_,private_,executable_,.tmpl) - Test with
chezmoi diffbeforechezmoi apply - Commit with appropriate scope from
.commitlintrc.js
- Edit item file in
home/dot_config/sketchybar/items/ - Reload SketchyBar:
sketchybar --reload - Check logs if not working:
log show --predicate 'process == "sketchybar"' --last 5m
- Edit
home/dot_config/yabai/executable_yabairc - Reload config:
yabai --restart-service - Check current layout:
yabai -m query --spaces --space
Component-specific documentation (Russian and English versions available):