Commit graph

307 commits

Author SHA1 Message Date
Jonny Barnes
dda3868321
Show gitignored files in nvim-tree and follow the open buffer
Two nvim-tree defaults that were quietly getting in the way.

filters.git_ignored defaults to true, so gitignored files are hidden. The
symptom was .env being absent from a project while .env.example sat right
there, which reads as a dotfile filter but is not: filters.dotfiles is already
false, so dotfiles show. The filter is git-aware, and .env was simply reported
ignored. Verified in a throwaway repo ignoring .env and vendor/ — both appear
now, and neither did before, with the ignored glyph to distinguish them.

The trade-off is real and is the reason for the default: vendor/ and
node_modules/ now show too. filters.exclude = { '.env' } was the narrower
option, exempting one name while keeping the rest hidden. Chose the broad
setting deliberately; `I` in the tree hides them again per session.

update_focused_file.enable defaults to false, so the tree never moved when a
file was opened from fzf-lua. Enabling it reveals the current buffer on
BufEnter, uncollapsing folders to reach it. Verified on a nested fixture:
opening src/deep/nested/target.php expanded all three folders and put the tree
cursor on the file. Focus stays in the file window, so it reveals rather than
steals, and it follows every buffer switch, not just fzf-lua.

Left update_root off. It would re-root the tree at files outside the current
root, which makes the tree wander into vendor/ — worse now that ignored files
are visible and easier to open by accident.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 21:18:55 +01:00
Jonny Barnes
f5ae360e7e
Document the neovim setup in its own README
Keymaps are discoverable in-editor by pressing <Space> and pausing, and are
written down separately, so they are deliberately not duplicated here. What was
not recorded anywhere was the surrounding context.

Covers the 0.12 floor, since autocomplete, pumborder, pummaxwidth, the nearest
completeopt value and vim.pack all require it; what bootstrap.sh symlinks where,
and why config/ is linked in as lua/config; and the vim.pack convention of one
file per plugin with versions pinned in the tracked lock file.

The rest is the behaviours that read as bugs until you know they are deliberate.
A standalone .php file gets no LSP at all, because phpactor sets
workspace_required and wants a project marker. Spell checking is on globally, in
code buffers too. netrw is disabled so `nvim .` opens nvim-tree, on the right.
Diagnostic signs are letters rather than icons.

Also restates the gitsigns global-mapping rationale already in the source, since
folding those maps into on_attach is the obvious tidy-up and it silently stops
them appearing in the which-key popup.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 17:06:52 +01:00
Jonny Barnes
d012a7f23e
Make the Claude Code statusline follow the terminal palette
The nine colours were hardcoded One Dark RGB via 38;2;R;G;B, so they did not
follow the light/dark switch. Measured against the tangere backgrounds they are
fine on dark (4.25-10.80:1) but collapse on light: orange 1.78, amber 1.70,
yellow 1.63, and 'white' — used for the token total — at 1.35:1, effectively
invisible.

Switched to palette indices, which resolve through the terminal's own palette and
so follow the ghostty tangere-light/tangere-dark swap with no detection and no
cost per render. 'white' becomes 39, default foreground, since it means primary
text. All seven colours actually used get distinct indices; blue and yellow are
unreferenced but converted too, so no RGB is left behind.

Contrast now clears WCAG AA in both modes: 5.77-14.26:1 on dark, 6.32-20.61:1 on
light.

Trade-off: tangere has no orange and its palette 2 is teal rather than green, so
'green' reads teal and the warm colours sit closer together than the One Dark
originals did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 14:02:01 +01:00
Jonny Barnes
39d52fbbcf
Record verified light-mode results for the theme hooks
Tested with the system actually in light mode rather than inferred from dark:

- the status bar switches in the same second client-light-theme fires
- a fresh nvim reports background=light, so the OSC 11 round trip through tmux
  to ghostty works and restarting nvim is genuinely sufficient
- delta resolves syntax-theme = GitHub, its light default, against Monokai
  Extended on dark, so it does detect the terminal background

Both the nvim and delta checks needed a real tty to be meaningful. Run with
stdout on a pipe they each fall back to their dark default, which looks like a
correct answer while proving nothing.

Also documents why the first Light switch did not move the status bar: tmux
enables the terminal's theme-reporting mode when a client attaches, so the
client that predated these hooks was never asked to report changes. A detach and
reattach fixes it, and a fresh server never sees it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 12:53:03 +01:00
Jonny Barnes
6b3ab420ad
Follow light/dark appearance in the tmux status bar
The status bar was five hardcoded tangere-dark colours, so in light mode the
pale #fdfdd9 text landed on a white background and became unreadable. That was
the real reason Auto appearance "never worked with the terminal setup" — ghostty
was switching correctly all along.

Split the colours into tmux-light.conf and tmux-dark.conf. The dark file is
extracted byte-exact from the previous config; the light file is the same layout
with each colour swapped for the tangere-light palette entry at the same index,
so roles are preserved (text on an accent uses the theme background, which
inverts from #1a2938 to #fdfdfa).

tmux 3.6+ learns the terminal's theme over OSC 2031, so this keys off the
appearance change itself rather than a schedule, and behaves identically whether
that came from Auto at sunrise/sunset or a manual toggle. Three hooks: the two
theme hooks react to a change, and client-attached covers a client attaching
mid-way, since those two only fire on a change. Sourcing is idempotent so the
overlap is harmless.

This replaces the dark-mode-notify launchd agent removed in 59d5622, which could
not have worked: it re-sourced .zshrc inside each shell, but the status bar
belongs to the tmux server.

Verified by round trip: flipping to Light switched #{client_theme} and applied
the light palette, and returning to Dark restored it. A running nvim does not
follow a live change (docs: the TUI sets 'background' on startup); noted in the
README.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 12:38:16 +01:00
Jonny Barnes
59d5622442
Remove dark-mode-notify, document the native approach
The launchd agent ran `pkill -usr1 zsh` on every appearance change, which made
every shell re-source .zshrc. That could never have achieved its goal: the tmux
status bar belongs to the tmux server and colours to a running nvim, so
re-sourcing a shell rc cannot retheme either. The one variable it set,
MACOS_APPEARANCE, was read by nothing. Its only real effect was firing on each
unlock — 5253 times on this machine, 3437 on the iMac — which is what drove the
~/.gitconfig.lock contention fixed in 583bbaa.

The agent and plist are removed from both machines; this drops the script.
ghostty, bat, delta and nvim all handle appearance natively, and tmux 3.6+
detects it over OSC 2031 (#{client_theme} already reports correctly). Wiring the
tmux client-light-theme/client-dark-theme hooks is left as the next step.

Also refreshes the stale parts of the README: the intro still explained
~/.gitconfig as a copy because .extra edited it, and the .extra example still
showed the `git config --global` calls that caused the lock errors, plus the
misspelled GIT_COMMITER_* vars. Following it would have reinstated the bug.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 11:37:24 +01:00
Jonny Barnes
583bbaa533
Move git identity to an included ~/.gitconfig.local
~/.extra ran five `git config --global` writes on every shell startup, to
re-assert identity and signing after bootstrap.sh copies gitconfig over
~/.gitconfig. The dark-mode-notify agent fires on wake/unlock and runs
`pkill -usr1 zsh`, so every shell re-sources .zshrc — and therefore .extra —
simultaneously. `git config` locks with O_EXCL and has no retry or timeout for
config files, so the concurrent writes raced and printed:

    error: could not lock config file /Users/jonny/.gitconfig: File exists

Identity and signing now live in an untracked ~/.gitconfig.local, included
last from gitconfig so it wins over anything above. bootstrap.sh seeds it from
gitconfig.local.template only when absent, so re-runs never clobber the real
signing key. No git writes happen on shell startup at all now.

Verified: fully-resolved config is unchanged apart from the new include.path;
author and committer both resolve from config with no GIT_* env vars set;
existing commits still verify. 12 concurrent sources of .extra are silent,
where the old version produced 27 lock errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 09:57:19 +01:00
Jonny Barnes
d245a83f2c
Add nvim-tree, on the right, toggled with <leader>e
Netrw is disabled, as nvim-tree needs to own directory buffers so
`nvim .` opens the tree rather than the two fighting over it. That
removes :Ex, so the Obsidian guide has been updated to point at
<leader>e instead.

No auto-open autocmd: `nvim <path>` opens just the file, and the tree
is there on <leader>e when it is wanted. Placing it on the right also
flips the split direction, so opening a file from the tree puts it to
the left rather than displacing the tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 20:36:39 +01:00
Jonny Barnes
865b52c2e5
Add fzf-lua for project navigation
Wraps the fzf binary already installed via brew, alongside rg and fd,
so it needs no plugin dependencies - unlike telescope, which would
also pull in plenary. Picks up nvim-web-devicons for file icons, which
is the first thing actually using that plugin.

Maps live under <leader>f: files, live grep, buffers, grep the word
under the cursor, and help tags. The intent is to stop treating netrw
as the way into a project and switch to jumping by name, leaving
buffers open and bouncing between them, rather than quitting out of
nvim to change file.

Netrw is untouched and still on :Ex for browsing an unfamiliar tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 18:39:48 +01:00
Jonny Barnes
e8e9bf0663
Fix which-key not seeing gitsigns maps, add diagnostic maps
The gitsigns keymaps were defined in on_attach, so they were
buffer-local and created asynchronously - gitsigns shells out to git
before attaching. which-key had already built its keymap tree for the
buffer by then, and it only invalidates that cache on BufReadPost,
BufNew and LspAttach, so maps added afterwards stayed invisible.
Buf:get() returns cached mode state unless explicitly passed `update`,
which is why re-entering the buffer didn't help either.

Mapping globally instead means the maps exist before which-key builds
any tree. The gitsigns API no-ops in buffers it hasn't attached to
(checked stage/reset/preview/blame/nav in a non-git directory), so the
only change is that the maps now exist everywhere rather than just in
git-tracked buffers.

Also puts the diagnostic float and quickfix list on <leader>d. Nvim
already binds <C-W>d and ]d/[d for these, so this is a rebinding for
discoverability rather than new capability.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 17:27:37 +01:00
Jonny Barnes
5d0688c827
Add which-key and nvim-web-devicons, tidy brew casks
which-key needs an icon backend and treats mini.icons and
nvim-web-devicons as equally viable optional deps, so devicons covers
it. Both are pure APIs with no visible effect on their own; devicons
self-initialises on require, so no setup() call.

Group labels for the <leader>h and <leader>t prefixes live in the
which-key config rather than next to the gitsigns maps they describe,
keeping which-key's config in one place. Worth moving if more plugins
start contributing prefixes.

The Nerd Font the glyphs need was installed by hand on this machine
but missing from brew.sh, so a fresh bootstrap would have rendered
every icon as tofu. Records it as a cask alongside the ghostty
font-family setting that already expects it.

Also drops the claude-code cask, which was never actually installed
here: brew tracks stable releases, and we want newer ones, so it comes
from Claude's own installer instead. Left a comment so it doesn't get
re-added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 14:26:59 +01:00
Jonny Barnes
509b16f543
Add gitsigns via vim.pack, track the pack lockfile
Restores plugin management after the v0.12 config rewrite dropped the
earlier `vim.pack.add` calls. Plugins now live in `config/plugins/`,
one file per plugin, so adding the next is a single require.

Sets `<leader>` to Space for the gitsigns hunk mappings, and pins
'signcolumn' open so git and diagnostic signs don't shift text.

The lockfile moves into the repo and is symlinked by bootstrap.sh, as
the vim.pack docs recommend, giving reproducible plugin revisions
across machines and a rollback path via git. vim.pack writes it with a
truncating open, so it follows the symlink rather than replacing it.

Drops the orphaned nvim-tree entry, unreferenced since the rewrite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 13:57:02 +01:00
Jonny Barnes
e1382f5c1f
Enable tmux focus-events
Claude Code CLI warns when focus-events is off. The option was already
present in the config but commented out from when it was first added.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 12:00:45 +01:00
Jonny Barnes
837efb3cca
Merge remote-tracking branch 'github/main' 2026-08-08 11:55:34 +01:00
Jonny Barnes
c7236f5a12
Switch Claude Code statusline to isaacaudet variant, show 7d usage
Add statusline.isaacaudet.sh and point the bootstrap symlink at it,
keeping the burnrate and original variants alongside.

The script already had a 7d rate-limit bar but gated it behind the
`full` width tier, so it only appeared at >=150 columns. Ungate it so it
renders wherever the 5h bar does, mirroring it exactly. The `full`-only
extra_usage bar is unchanged.

To pay for the ~14 columns that costs, the reset timestamps are now
`full`-only (the 5h one previously also showed at `wide`), and the model
name is shortened at `split` as well as `narrow` - with the 7d bar added
a `split` line came to 82 visible columns against a 76-column budget and
wrapped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 11:54:05 +01:00
Jonny Barnes
1280f864ae
Fix two brew install lines that error out
`brew install gnu-sed --with-default-names` fails with "invalid option"
- Homebrew dropped per-formula option flags years ago. The flag existed
to install GNU sed as `sed` rather than `gsed`, which is now the
opposite of what we want, so drop it and note why in the comment.

`oven-sh/bun/bun` no longer resolves; bun has since moved into
homebrew-core, so install it by its plain name. This line has been
failing on every bootstrap, which is why bun was never actually
installed.

Neither aborted the script (there is no `set -e`), they just failed
their own install and carried on. Verified all 47 formulae and 6 casks
now resolve and none are deprecated or disabled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 11:53:54 +01:00
Jonny Barnes
9930bbc009
Stop shadowing BSD coreutils with GNU versions on PATH
Prepending the coreutils/findutils/gnu-sed/grep gnubin dirs put GNU
stat, date, sed, grep and find on the PATH under their un-prefixed
names, which silently breaks any script written against the macOS
versions. Portable scripts typically probe BSD-first and fall back to
GNU, so the BSD probe succeeds against a GNU binary that means something
else entirely and the fallback never fires.

The Claude Code statusline was a live example: it reads a cache file's
mtime with `stat -f %m`, which GNU stat parses as a *filesystem* format
string. That emits a multi-line blob, the following arithmetic hits a
syntax error, and because an arithmetic error aborts the shell the
enclosing function returned early - so the git branch segment silently
vanished on every warm-cache render. Its `date -j -r` reset timestamps
failed the same way.

Homebrew installs the g-prefixed variants into $HOMEBREW_PREFIX/bin
regardless, so gstat / gdate / gsed / ggrep / gfind still give GNU
behaviour on demand. Note BSD sed needs `sed -i ''` rather than `sed -i`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 11:53:40 +01:00
43e5d5ed85
Only load fnm sheldon plugin on macOS
On the server, fnm isn't installed since system nodejs is used instead.
The zsh-fnm plugin's own fallback silently curl-installs fnm when missing,
and its --use-on-cd hook then prompts on every cd since no default version
is fnm-managed there. Gate the plugin to Darwin only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3jcSVn51hiw58f7jPWrpN
2026-08-04 22:30:41 +01:00
Jonny Barnes
8cc69aa6f3
Fix Opus statusline hue rendering as black in light theme
Hue 226 (#ffff00) has a contrast ratio of 1.05 against the tangere-light
background (#fdfdfa), below the minimum-contrast = 1.1 set in the ghostty
config. Ghostty then substitutes the foreground for whichever of black or
white has more contrast, so against a near-white background that letter of
the model name rendered black.

Swap 226 for 184 (#d7d700, ratio 1.51 light / 9.60 dark) in the Opus ramp
and the unknown-model fallback, the only two palettes that used it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 17:35:33 +01:00
Jonny Barnes
644c52d4b4
Switch Claude Code statusline to burnrate variant
Keep the previous statusline as statusline.original.sh and add
statusline.burnrate.sh from Gui-Gou/claude-statusline-burnrate, which
shows weekly/5h plan usage and a sustainable burn rate.

bootstrap.sh now links the burnrate script unconditionally - the old
`test -L` guard would have left an existing symlink pointing at the
previous script. jq is a hard dependency of the new script, so add it
to brew.sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 14:40:40 +01:00
Jonny Barnes
f5b8624814
Improve zsh performance 2026-06-26 14:47:32 +01:00
b441c47098
Make tmux work with claude installed via claude.com install.sh script 2026-06-10 15:26:01 +01:00
a69eb78f95
Improve prompt loading 2026-06-06 18:10:35 +01:00
Jonny Barnes
d3b54ea921
Updated neovim config for v0.12 2026-05-31 20:33:23 +01:00
Jonny Barnes
dec884da2f
Tidy up brew install script 2026-04-20 16:11:07 +01:00
2f3e3393d8
Update cp-torrent command 2026-04-12 11:24:18 +01:00
9028f0fe67
Fox ghostty config 2026-04-02 10:59:23 +01:00
Jonny Barnes
7b40ed544c
Trying out a new font 2026-04-01 21:18:23 +01:00
Jonny Barnes
f9e4c65001
Add claude statusline to my dotfiles 2026-03-28 16:51:14 +00:00
Jonny Barnes
2d18961ebc
Stay in tmux of there are other windows when quitting 2026-03-28 16:50:34 +00:00
Jonny Barnes
f258813771
Allow tmux to let links be clickable 2026-03-22 18:00:10 +00:00
Jonny Barnes
c8ea7cc820
Add Obsidian CLI 2026-02-28 21:13:48 +00:00
Jonny Barnes
dd0d06fa1d
Add docker commands from user install 2026-02-28 21:11:11 +00:00
6d645999f2
Add phpactor support to neovim with default settings 2026-02-15 17:03:34 +00:00
34458b17f5
No need for alt key changes 2026-02-15 17:01:41 +00:00
ffd895b1fe
Use pack.add for plugns
Needs neovim >= 0.12
2026-02-13 22:25:08 +00:00
5ad13bcd09
Initial tidy up of neovim config 2026-02-13 21:06:00 +00:00
98bd888775
Tweak ghostty config 2026-02-13 16:11:02 +00:00
6c23a03412
Improvements to lazygit/tmux/ghossty configs 2026-01-30 14:42:51 +00:00
ab0b63bc87
Update ghostty config 2026-01-19 18:27:04 +00:00
f108939b68
Improve tmux config
Mainly adds a better styling to the status bar
2026-01-18 17:27:15 +00:00
b3a2238d30
Removing vim configuration 2026-01-15 18:26:29 +00:00
bca7ed3fe9
Claude Code added native shift+enter support, no need for terminal hack 2026-01-09 16:59:30 +00:00
249d84fe79
Tweak ghostty config 2026-01-09 16:55:53 +00:00
d7bc6bb72f
Add location of rainfrog config 2026-01-09 16:50:31 +00:00
ab3e6950c7
Tweak cursor colour in tangere theme 2025-10-26 16:59:30 +00:00
88a8dd1698
Update ghostty config to use custom Tangere theme 2025-10-26 11:18:04 +00:00
e632a40580
Fix fnm to look for parent nvmrc files 2025-10-13 20:14:34 +01:00
fe2213fe91
Add yay+fzf alias 2025-10-10 13:15:08 +01:00
cc042d5bd7
Ghostty changed its theme names in v1.2.0 2025-09-16 16:05:45 +01:00