setup_env/CLAUDE.md

163 lines
7.2 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository Overview
Personal Linux development environment setup. Clone and run one script to get a consistent shell and editor across machines.
## Key Commands
### Fresh machine setup
```bash
git clone git@gitea.hptrow.me:pt/setup_env.git ~/setup_env
cd ~/setup_env && ./setup_env.sh
```
`setup_env.sh` installs packages, downloads Neovim, clones plugin managers, deploys all dotfile symlinks, and sets up NvChad.
### Day-to-day sync
```bash
cd ~/setup_env && ./sync.sh
```
Pulls setup_env and nvim config repos, redeploys symlinks. Safe to run anytime.
### Optional tool installs (run manually per machine)
```bash
./install_postgres.sh # PostgreSQL from official apt repository
./install_python3.sh # Latest Python 3 from deadsnakes PPA (includes python3-venv)
./install_node.sh # Node.js via nvm (needed for prettier formatter in nvim)
./install_java_dev.sh # SDKMAN for Java development
./install_visidata.sh # VisiData for terminal data exploration
./reinstall_nvchad.sh # Wipe and reinstall NvChad from scratch
```
### After plugin manager install
- **Tmux**: press `Ctrl-b + I` to install TPM plugins
- **Vim**: run `:PluginInstall` inside vim
## Architecture
### Scripts
- `setup_env.sh` — fresh machine only. Installs everything in order.
- `sync.sh` — day-to-day. Pulls repos and redeploys symlinks. No apt, no sudo.
- `_lib.sh` — shared deploy functions sourced by both scripts.
- `install_neovim.sh` — downloads Neovim v0.11.3 to `/opt/`, auto-adds to `.bashrc_paths`. Called by `setup_env.sh`.
- `install_nvchad.sh` — clones nvim config from gitea on fresh install, or `git pull`s if already present. Called by both `setup_env.sh` and `sync.sh`.
- `reinstall_nvchad.sh` — wipes all nvim data and re-runs `install_nvchad.sh`. Run manually when nvim is broken.
- `install_*.sh` — optional installs, run manually per machine.
### Dotfile Management
Symlink-based deployment. Editing `~/.<file>` directly edits the repo file. `git status` shows config drift.
`deploy_configs`, `deploy_bin`, and `deploy_nvim` (in `_lib.sh`) handle symlinking. `create_symlink` skips if already correct. `migrate_and_link` (used for gitignored files) migrates existing real files into the repo, or bootstraps from `_example` if nothing exists.
**Tracked dotfiles** (in git):
- `dotfiles/.bashrc` — main shell config
- `dotfiles/.vimrc`, `.gitconfig`, `.tmux.conf`, `.psqlrc`, `.pspgconf`
- `dotfiles/bin/td` — time-tracking CLI
- `dotfiles/nvim/td.lua`, `td_mappings.lua` — nvim lua modules
**Gitignored** (machine-specific, auto-bootstrapped from examples):
- `dotfiles/.bashrc_local` — secrets and credentials
- `dotfiles/.bashrc_paths` — PATH additions and tool inits
### Two-repo nvim setup
The nvim config lives in a separate repo at `git@gitea.hptrow.me:pt/nvchad.git` (`customize` branch), deployed to `~/.config/nvim`. `install_nvchad.sh` manages it.
`dotfiles/nvim/td.lua` and `td_mappings.lua` are deployed as symlinks into `~/.config/nvim/lua/` by `deploy_nvim`. The nvim repo's `mappings.lua` loads them via `require "td_mappings"`. The nvim repo does not track these files — setup_env owns them.
**Dependency**: `deploy_nvim` must run after `install_nvchad.sh` has created `~/.config/nvim/lua/`. On a fresh machine this is handled automatically by `setup_env.sh` ordering. On existing machines `sync.sh` handles it.
## Custom Bash Workflow
### Database Query Management
PostgreSQL (env var `$PG` defined in `.bashrc_local`):
- `xnspa([args])` — fzf-select an open nvim swap file, run with `$PG`, output CSV to VisiData. Accepts extra psql args.
- `xnsp` — same, output to pspg
- `xns` — same, raw output
SQL Server (env vars `$MS`, `$MSC`, `$MSW` in `.bashrc_local`):
- `xmspa()` — fzf-select swap file, run with `$MSC`, pipe-delimited output to VisiData
- `xmsp` — same, output to pspg
- `xms` — same, raw output
General:
- `ons` — list open nvim swap files in current directory tree
### Git Aliases
- `gs` — git status short
- `ga` — interactive git add via fzf
- `gx` — interactive git checkout via fzf
- `vc()``git add -u`, commit with timestamp, push
- `gr`, `gc`, `gd`, `gl` — reset, commit, difftool, log
### Todo Grep (rg-based)
- `td` — find unchecked todos
- `tdp` / `tdtp` — priority todos (🔼 / ⏫)
- `tdo` / `tdop` — open todo in nvim at exact line
### Time Tracking
Shell wrappers around `dotfiles/bin/td` (bypasses the `td` rg alias via `command td`):
- `tstart` / `tstop` / `treport` / `tweek`
Nvim keymaps (via `td_mappings.lua`): `<leader>ts/tp/tr/tw`
### Other Aliases
- `cj` — cd to journal
- `jr` / `hc` — sync journal / hc notes
## How Neovim understands code (tree-sitter vs LSP)
Two parallel systems, different jobs:
```
tree-sitter: file → parser (.so grammar) → syntax tree → highlighting / aerial outline / folding
LSP: file → language server process → diagnostics / completion / hover / go-to-def
```
**Tree-sitter** is a structural parser. It turns text into a tree of named syntax nodes
(`create_table`, `create_function`, etc.) but knows nothing about semantics — it can't
tell you a column doesn't exist. Each language has a community-maintained grammar that
gets compiled to a `.so` file. `nvim-treesitter` manages downloading and compiling these.
Plugins like aerial ship `.scm` query files that pattern-match against node types in that
tree to extract symbols.
**LSP** (Language Server Protocol) is a separate process (installed via Mason) that
understands the language semantically — it can autocomplete column names, validate queries
against a real schema, etc. It has no idea tree-sitter exists.
Aerial can use either backend. If an LSP is attached to the file, aerial can ask it for
document symbols and skip tree-sitter entirely.
**Where things break:** if a `.scm` query references a node type (e.g. `create_policy`)
that the installed grammar `.so` doesn't define, tree-sitter rejects the whole query at
parse time — before it even looks at your file. Fix: override the query in
`~/.config/nvim/queries/<lang>/` so your version wins over the plugin's copy.
## Treesitter Query Overrides
`dotfiles/nvim/queries/` contains local query overrides that shadow plugin-provided queries in `~/.config/nvim/queries/`. They are deployed as symlinks by `deploy_nvim` in `_lib.sh` (alongside `lua/` and `lua/plugins/`).
Current overrides:
- **`queries/sql/aerial.scm`** — aerial.nvim's upstream SQL query includes `(create_policy ...)`, which is not a valid node type in the installed tree-sitter-sql grammar and causes aerial to crash on SQL files. This file is a full replacement with `create_policy` commented out. If a future `TSUpdate sql` adds the node, remove the comment and retire the override.
## Machine-specific Configuration
`.bashrc` sources two gitignored files:
- **`.bashrc_local`** — secrets: DB connection strings, passwords, tokens
- **`.bashrc_paths`** — PATH additions: nvim, cargo, nvm, java, etc.
Both are auto-bootstrapped from `_example` files on first `setup_env.sh` run. When a tool appends to `.bashrc`, `git status` shows it — move those lines to `.bashrc_paths`.
## Git Commit Style
Simple lowercase messages: "add cargo", "visidata", "fix nv alias path"