Compare commits
4 Commits
ed52bf7b93
...
d0047a1c7b
| Author | SHA1 | Date | |
|---|---|---|---|
| d0047a1c7b | |||
| d9d4da8d0b | |||
| 5dc9962fc5 | |||
| 11cc64bd4c |
@@ -0,0 +1,71 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## What This Is
|
||||
|
||||
A batteries-loaded macOS rice — cross-platform Nix configuration (nix-darwin + NixOS + home-manager) for user `df`. The active system is `m2n1` — an Apple Silicon Mac running nix-darwin.
|
||||
|
||||
## Philosophy
|
||||
|
||||
This repo strives for the **best possible macOS setup** with seamless UX:
|
||||
|
||||
- **Better defaults everywhere** — keyboard, trackpad, Dock, Finder, screenshots, window management, etc. If macOS has a bad default, override it.
|
||||
- **Batteries included** — tools, shell plugins, keybindings, and integrations should work out of the box. No manual post-install steps.
|
||||
- **Rice it** — the setup should look and feel polished. Consistent theming, clean status bars, good typography.
|
||||
- **Research before implementing** — when adding or changing something, check the internet for the best current practices, latest options, and what power users recommend. Don't guess.
|
||||
- **Test it works** — after making changes, run `darwin-rebuild switch` and verify the setting actually took effect (e.g. `defaults read` for macOS prefs, `which <pkg>` for packages, checking service status for daemons). Never assume a fix works — always confirm.
|
||||
- **Teach debugging** — always explain *how* you verified something works and *how* the user can check it themselves. Show the proof: the command to run, what the output should look like, and what it means. The user should learn to debug and verify on their own, not just trust the output.
|
||||
- **Stay current** — nix-darwin, home-manager, and macOS evolve. When touching a module, check if there are newer/better options available.
|
||||
- **Nix-only** — never use `brew install`, `nix-env -i`, or any imperative package management. Everything goes through the flake: system packages in `darwin/configuration.nix`, user packages in `home-manager/modules/`. If it's not declared in Nix, it doesn't exist.
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Primary build+switch for macOS (requires sudo)
|
||||
sudo darwin-rebuild build --flake ~/bankrupt/#m2n1
|
||||
sudo darwin-rebuild switch --flake ~/bankrupt/#m2n1
|
||||
|
||||
# Or via Makefile (auto-detects hostname)
|
||||
make darwin-switch
|
||||
|
||||
# Update flake inputs
|
||||
make update
|
||||
|
||||
# Format nix files
|
||||
nix fmt
|
||||
|
||||
# Validate flake
|
||||
nix flake check
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
flake.nix # Entry point: inputs, overlays, system configs
|
||||
├── common.nix # Shared nix settings (caches, overlays, GC)
|
||||
├── darwin/configuration.nix # m2n1 system config (imports yabai.nix, skhd.nix)
|
||||
├── nixos/configuration.nix # Template NixOS config
|
||||
├── overlays/default.nix # Package overlays (emacs, unstable, custom)
|
||||
└── home-manager/
|
||||
├── home.nix # Imports all modules below
|
||||
├── common.nix # Base home-manager settings
|
||||
├── platform/ # darwin.nix / linux.nix (conditional via stdenv.isDarwin)
|
||||
└── modules/ # Feature modules: git, shells, fish, tmux, kitty, neovim, doom-emacs
|
||||
└── inbox/ # packages.nix (large package list), inbox.nix (dev tools)
|
||||
```
|
||||
|
||||
## Key Patterns
|
||||
|
||||
- **Platform conditionals**: `lib.mkIf pkgs.stdenv.isDarwin` / `lib.mkIf pkgs.stdenv.isLinux`
|
||||
- **Flake inputs**: nixpkgs 25.05, home-manager release-25.05, nix-darwin darwin-25.05
|
||||
- **Determinate Nix**: `nix.enable = false` in darwin config (conflicts with nix-darwin's daemon)
|
||||
- **Overlays** in `overlays/default.nix` feed into `common.nix` and are applied system-wide
|
||||
|
||||
## Workflow Notes
|
||||
|
||||
- To add a new package: edit `home-manager/modules/inbox/packages.nix` (user-level) or `darwin/configuration.nix` (system-level)
|
||||
- To add a new tool module: create `home-manager/modules/<tool>.nix` and import it in `home-manager/home.nix`
|
||||
- When build fails, read the error output carefully — common issues are hash mismatches (run `nix flake update`) or missing inputs
|
||||
- **After changing `system.defaults`**: run `darwin-rebuild switch`, then verify with `defaults read <domain> <key>`. Some settings need a logout/restart to take effect.
|
||||
- **When adding a new default or tool**: search the web for current best practices before implementing. Check nix-darwin options, popular dotfile repos, and macOS power-user guides.
|
||||
@@ -50,6 +50,7 @@
|
||||
users.users.df = {
|
||||
name = "df";
|
||||
home = "/Users/df";
|
||||
shell = pkgs.fish;
|
||||
};
|
||||
|
||||
# Set primary user for system defaults
|
||||
|
||||
+40
-34
@@ -1,5 +1,8 @@
|
||||
# skhd (Simple Hotkey Daemon) configuration for macOS
|
||||
# Uses nix-darwin's services.skhd module
|
||||
#
|
||||
# Directional keys use Emacs-style BPNF:
|
||||
# b = west (backward), n = south (next), p = north (previous), f = east (forward)
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
@@ -12,7 +15,7 @@ in {
|
||||
enable = true;
|
||||
skhdConfig = ''
|
||||
## Navigation (${super} - ...)
|
||||
# Space Navigation (four spaces per display): ${super} - {1, 2, 3, 4}
|
||||
# Space Navigation: ${super} - {1-9, 0}
|
||||
${super} - 1 : yabai -m space --focus 1
|
||||
${super} - 2 : yabai -m space --focus 2
|
||||
${super} - 3 : yabai -m space --focus 3
|
||||
@@ -24,32 +27,32 @@ in {
|
||||
${super} - 9 : yabai -m space --focus 9
|
||||
${super} - 0 : yabai -m space --focus 0
|
||||
|
||||
# Window Navigation (through display borders): ${super} - {h, j, k, l}
|
||||
${super} - h : yabai -m window --focus west || yabai -m display --focus west
|
||||
${super} - j : yabai -m window --focus south || yabai -m display --focus south
|
||||
${super} - k : yabai -m window --focus north || yabai -m display --focus north
|
||||
${super} - l : yabai -m window --focus east || yabai -m display --focus east
|
||||
# Window Navigation (through display borders): ${super} - {b, n, p, f}
|
||||
${super} - b : yabai -m window --focus west || yabai -m display --focus west
|
||||
${super} - n : yabai -m window --focus south || yabai -m display --focus south
|
||||
${super} - p : yabai -m window --focus north || yabai -m display --focus north
|
||||
${super} - f : yabai -m window --focus east || yabai -m display --focus east
|
||||
|
||||
# Float / Unfloat window: ${super} - space
|
||||
# ${super} - space : yabai -m window --toggle float; sketchybar --trigger window_focus
|
||||
|
||||
# Make window zoom to fullscreen: shift + ${super} - f
|
||||
shift + ${super} - f : yabai -m window --toggle zoom-fullscreen; sketchybar --trigger window_focus
|
||||
# Make window zoom to fullscreen: shift + ${super} - m
|
||||
shift + ${super} - m : yabai -m window --toggle zoom-fullscreen; sketchybar --trigger window_focus
|
||||
|
||||
# Make window zoom to parent node: ${super} - f
|
||||
${super} - f : yabai -m window --toggle zoom-parent; sketchybar --trigger window_focus
|
||||
# Make window zoom to parent node: ${super} - m
|
||||
${super} - m : yabai -m window --toggle zoom-parent; sketchybar --trigger window_focus
|
||||
|
||||
## Window Movement (shift + ${super} - ...)
|
||||
# Moving windows in spaces: shift + ${super} - {h, j, k, l}
|
||||
shift + ${super} - h : yabai -m window --warp west || $(yabai -m window --display west && sketchybar --trigger windows_on_spaces && yabai -m display --focus west && yabai -m window --warp last) || yabai -m window --move rel:-10:0
|
||||
shift + ${super} - j : yabai -m window --warp south || $(yabai -m window --display south && sketchybar --trigger windows_on_spaces && yabai -m display --focus south) || yabai -m window --move rel:0:10
|
||||
shift + ${super} - k : yabai -m window --warp north || $(yabai -m window --display north && sketchybar --trigger windows_on_spaces && yabai -m display --focus north) || yabai -m window --move rel:0:-10
|
||||
shift + ${super} - l : yabai -m window --warp east || $(yabai -m window --display east && sketchybar --trigger windows_on_spaces && yabai -m display --focus east && yabai -m window --warp first) || yabai -m window --move rel:10:0
|
||||
# Swap/warp windows directionally: shift + ${super} - {b, n, p, f}
|
||||
shift + ${super} - b : yabai -m window --swap west || $(yabai -m window --display west && sketchybar --trigger windows_on_spaces && yabai -m display --focus west && yabai -m window --warp last) || yabai -m window --move rel:-10:0
|
||||
shift + ${super} - n : yabai -m window --swap south || $(yabai -m window --display south && sketchybar --trigger windows_on_spaces && yabai -m display --focus south) || yabai -m window --move rel:0:10
|
||||
shift + ${super} - p : yabai -m window --swap north || $(yabai -m window --display north && sketchybar --trigger windows_on_spaces && yabai -m display --focus north) || yabai -m window --move rel:0:-10
|
||||
shift + ${super} - f : yabai -m window --swap east || $(yabai -m window --display east && sketchybar --trigger windows_on_spaces && yabai -m display --focus east && yabai -m window --warp first) || yabai -m window --move rel:10:0
|
||||
|
||||
# Toggle split orientation of the selected windows node: shift + ${super} - s
|
||||
shift + ${super} - s : yabai -m window --toggle split
|
||||
|
||||
# Moving windows between spaces: shift + ${super} - {1, 2, 3, 4, p, n } (Assumes 4 Spaces Max per Display)
|
||||
# Moving windows between spaces: shift + ${super} - {1, 2, 3, 4, [, ] }
|
||||
shift + ${super} - 1 : DISPLAY="$(yabai -m query --displays --display | jq '.index')";\
|
||||
yabai -m window --space $((1+4*($DISPLAY - 1)));\
|
||||
sketchybar --trigger windows_on_spaces
|
||||
@@ -66,30 +69,30 @@ in {
|
||||
yabai -m window --space $((4+4*($DISPLAY - 1)));\
|
||||
sketchybar --trigger windows_on_spaces
|
||||
|
||||
shift + ${super} - p : yabai -m window --space prev; yabai -m space --focus prev; sketchybar --trigger windows_on_spaces
|
||||
shift + ${super} - n : yabai -m window --space next; yabai -m space --focus next; sketchybar --trigger windows_on_spaces
|
||||
shift + ${super} - 0x21 : yabai -m window --space prev; yabai -m space --focus prev; sketchybar --trigger windows_on_spaces
|
||||
shift + ${super} - 0x1E : yabai -m window --space next; yabai -m space --focus next; sketchybar --trigger windows_on_spaces
|
||||
|
||||
# Mirror Space on X and Y Axis: shift + ${super} - {x, y}
|
||||
shift + ${super} - x : yabai -m space --mirror x-axis
|
||||
shift + ${super} - y : yabai -m space --mirror y-axis
|
||||
|
||||
## Stacks (shift + ctrl - ...)
|
||||
# Add the active window to the window or stack to the {direction}: shift + ctrl - {h, j, k, l}
|
||||
shift + ctrl - h : yabai -m window west --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - j : yabai -m window south --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - k : yabai -m window north --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - l : yabai -m window east --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
# Add the active window to the window or stack to the {direction}: shift + ctrl - {b, n, p, f}
|
||||
shift + ctrl - b : yabai -m window west --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - n : yabai -m window south --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - p : yabai -m window north --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
shift + ctrl - f : yabai -m window east --stack $(yabai -m query --windows --window | jq -r '.id'); sketchybar --trigger window_focus
|
||||
|
||||
# Stack Navigation: shift + ctrl - {n, p}
|
||||
shift + ctrl - n : yabai -m window --focus stack.next
|
||||
shift + ctrl - p : yabai -m window --focus stack.prev
|
||||
# Stack Navigation: shift + ctrl - {], [}
|
||||
shift + ctrl - 0x1E : yabai -m window --focus stack.next
|
||||
shift + ctrl - 0x21 : yabai -m window --focus stack.prev
|
||||
|
||||
## Resize (ctrl + ${super} - ...)
|
||||
# Resize windows: ctrl + ${super} - {h, j, k, l}
|
||||
ctrl + ${super} - h : yabai -m window --resize right:-100:0 || yabai -m window --resize left:-100:0
|
||||
ctrl + ${super} - j : yabai -m window --resize bottom:0:100 || yabai -m window --resize top:0:100
|
||||
ctrl + ${super} - k : yabai -m window --resize bottom:0:-100 || yabai -m window --resize top:0:-100
|
||||
ctrl + ${super} - l : yabai -m window --resize right:100:0 || yabai -m window --resize left:100:0
|
||||
# Resize windows: ctrl + ${super} - {b, n, p, f}
|
||||
ctrl + ${super} - b : yabai -m window --resize right:-100:0 || yabai -m window --resize left:-100:0
|
||||
ctrl + ${super} - n : yabai -m window --resize bottom:0:100 || yabai -m window --resize top:0:100
|
||||
ctrl + ${super} - p : yabai -m window --resize bottom:0:-100 || yabai -m window --resize top:0:-100
|
||||
ctrl + ${super} - f : yabai -m window --resize right:100:0 || yabai -m window --resize left:100:0
|
||||
|
||||
# Equalize size of windows: ctrl + ${super} - e
|
||||
ctrl + ${super} - e : yabai -m space --balance
|
||||
@@ -97,15 +100,18 @@ in {
|
||||
# Enable / Disable gaps in current workspace: ctrl + ${super} - g
|
||||
ctrl + ${super} - g : yabai -m space --toggle padding; yabai -m space --toggle gap
|
||||
|
||||
# Enable / Disable window borders in current workspace: ctrl + ${super} - b
|
||||
ctrl + ${super} - b : yabai -m config window_border off
|
||||
shift + ctrl + ${super} - b : yabai -m config window_border on
|
||||
# Enable / Disable window borders in current workspace: ctrl + ${super} - o
|
||||
ctrl + ${super} - o : yabai -m config window_border off
|
||||
shift + ctrl + ${super} - o : yabai -m config window_border on
|
||||
|
||||
## Misc
|
||||
# Open new Kitty window
|
||||
${super} - return : kitty --single-instance -d ~
|
||||
# Bring Kitty window to current space
|
||||
${super} - o : yabai -m window $(yabai -m query --windows | jq '.[] | select(.app==".kitty-wrapped") | .id') --space $(yabai -m query --spaces | jq '.[] | select(.has-focus==1) .id')
|
||||
|
||||
# Open Emacs client
|
||||
${super} - z : emacsclient -nc
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
+3
-3
@@ -58,10 +58,10 @@
|
||||
fold ; (nigh) universal code folding
|
||||
(format +onsave) ; automated prettiness
|
||||
;;god ; run Emacs commands without modifier keys
|
||||
lispy ; vim for lisp, for people who don't like vim
|
||||
;;lispy ; vim for lisp, for people who don't like vim
|
||||
multiple-cursors ; editing in many places at once
|
||||
objed ; text object editing for the innocent
|
||||
parinfer ; turn lisp into python, sort of
|
||||
;;objed ; text object editing for the innocent
|
||||
;;parinfer ; turn lisp into python, sort of
|
||||
rotate-text ; cycle region at point between text candidates
|
||||
snippets ; my elves. They type so I don't have to
|
||||
word-wrap ; soft wrapping with language-aware indent
|
||||
|
||||
@@ -105,6 +105,9 @@
|
||||
if test -z "$LC_ALL"
|
||||
set -gx LC_ALL en_US.UTF-8
|
||||
end
|
||||
|
||||
# Bun global bin directory
|
||||
fish_add_path -g $HOME/.bun/bin
|
||||
'';
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
gitsigns = true,
|
||||
treesitter = true,
|
||||
telescope = { enabled = true },
|
||||
neo_tree = true,
|
||||
neotree = true,
|
||||
indent_blankline = { enabled = true },
|
||||
native_lsp = { enabled = true },
|
||||
},
|
||||
|
||||
@@ -23,14 +23,23 @@
|
||||
mouse = true;
|
||||
prefix = "C-a"; # More ergonomic than C-b
|
||||
escapeTime = 0; # No delay for escape (important for vim)
|
||||
sensibleOnTop = true;
|
||||
sensibleOnTop = false; # sensible's reattach-to-user-namespace overrides default-shell on macOS
|
||||
shell = "${pkgs.fish}/bin/fish";
|
||||
|
||||
plugins = with pkgs.tmuxPlugins; [
|
||||
# Core essentials
|
||||
sensible
|
||||
# Core essentials (sensible removed — its settings are already in extraConfig
|
||||
# and it was adding ~140ms startup + causing the reattach-to-user-namespace /bin/sh bug)
|
||||
yank # System clipboard integration
|
||||
vim-tmux-navigator # Seamless vim/tmux pane navigation
|
||||
better-mouse-mode # Enhanced mouse support
|
||||
{
|
||||
plugin = better-mouse-mode;
|
||||
extraConfig = ''
|
||||
set -g @scroll-without-changing-pane 'on'
|
||||
set -g @scroll-in-moused-over-pane 'on'
|
||||
set -g @emulate-scroll-for-no-mouse-alternate-buffer 'on'
|
||||
set -g @scroll-speed-num-lines-per-scroll '3'
|
||||
'';
|
||||
}
|
||||
|
||||
# Session persistence - survive reboots
|
||||
{
|
||||
@@ -82,7 +91,7 @@
|
||||
|
||||
# Status bar modules
|
||||
set -g @catppuccin_status_modules_right 'session date_time'
|
||||
set -g @catppuccin_status_modules_left ''''
|
||||
set -g @catppuccin_status_modules_left ""
|
||||
set -g @catppuccin_date_time_text '%H:%M'
|
||||
'';
|
||||
}
|
||||
@@ -93,9 +102,19 @@
|
||||
# GENERAL SETTINGS
|
||||
# ============================================
|
||||
|
||||
# Force fish as the shell
|
||||
set -g default-command "${pkgs.fish}/bin/fish"
|
||||
|
||||
# Emacs keybindings in tmux command prompt (prefix + :)
|
||||
set -g status-keys emacs
|
||||
|
||||
# True color support
|
||||
set -ag terminal-overrides ",xterm-256color:RGB"
|
||||
set -ag terminal-overrides ",*256col*:Tc"
|
||||
|
||||
# Extended keys — lets tmux forward Shift+Enter, Ctrl+Enter, etc.
|
||||
set -s extended-keys on
|
||||
set -as terminal-features 'xterm*:extkeys'
|
||||
|
||||
# Undercurl support (for spell checking in nvim)
|
||||
set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm'
|
||||
|
||||
Reference in New Issue
Block a user