From 226cdd64c611c48b0ce6f3210d30a05941f34c90 Mon Sep 17 00:00:00 2001 From: Paul Trowbridge Date: Sun, 10 May 2026 03:19:16 -0400 Subject: [PATCH] move readme to root, update readme and claude.md to reflect current setup --- CLAUDE.md | 191 +++++++++++++++++++-------------------------- README.md | 108 +++++++++++++++++++++++++ dotfiles/README.md | 94 ---------------------- 3 files changed, 190 insertions(+), 203 deletions(-) create mode 100644 README.md delete mode 100644 dotfiles/README.md diff --git a/CLAUDE.md b/CLAUDE.md index 7b93987..7bfeca7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,147 +4,120 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Repository Overview -This is a personal development environment setup repository containing: -- Shell scripts for automated installation of development tools -- Dotfiles for bash, vim, tmux, git, psql, and pspg -- The main `setup_env.sh` script deploys dotfiles as symlinks and installs base packages +Personal Linux development environment setup. Clone and run one script to get a consistent shell and editor across machines. ## Key Commands -### Environment Setup +### Fresh machine setup ```bash -# Initial setup - installs packages, plugin managers, and creates symlinks -./setup_env.sh +git clone git@gitea.hptrow.me:pt/setup_env.git ~/setup_env +cd ~/setup_env && ./setup_env.sh +``` -# Individual tool installations +`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 ./install_java_dev.sh # SDKMAN for Java development -./install_neovim.sh # Latest Neovim release, extracted to /opt/ -./install_nvchad.sh # NvChad Neovim config ./install_visidata.sh # VisiData for terminal data exploration ``` -After running `setup_env.sh`, activate plugins: -- **Tmux**: Press `prefix + I` (Ctrl-b + I) to install TPM plugins -- **Vim**: Run `:PluginInstall` inside vim to install Vundle plugins - - -### Git Operations -```bash -# Automated commit and push (defined in .bashrc) -vc # git add . && commit with timestamp && push - -# Custom git aliases (defined in .gitconfig) -git pushall # Push to all remotes -``` +### After plugin manager install +- **Tmux**: press `Ctrl-b + I` to install TPM plugins +- **Vim**: run `:PluginInstall` inside vim ## Architecture -### Dotfile Management System -The repository uses **symlink-based configuration deployment**. When `setup_env.sh` runs: -1. `deploy_configs` symlinks each dotfile in `dotfiles/` to `~/.` (backing up any existing file) -2. `deploy_bin` symlinks every file in `dotfiles/bin/` to `~/.local/bin/` -3. This allows version control of configs and user-local scripts while keeping them in their expected locations +### Scripts -All dotfiles are symlinked, not copied. Editing `~/.` directly modifies files in the repository. +- `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 latest Neovim binary to `/opt/`. 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`. +- `install_*.sh` — optional installs, run manually per machine. +### Dotfile Management -**Critical Files:** -- `dotfiles/.bashrc` - Main bash configuration with extensive aliases and functions -- `dotfiles/.bashrc_local` - Machine-specific secrets and credentials (PG, MS connection strings) -- `dotfiles/.bashrc_local_example` - Template for `.bashrc_local` -- `dotfiles/.bashrc_paths` - Machine-specific PATH additions and tool inits -- `dotfiles/.bashrc_paths_example` - Template for `.bashrc_paths` -- `dotfiles/.vimrc` - Vim configuration using Vundle plugin manager -- `dotfiles/.tmux.conf` - Tmux configuration with vim-style pane navigation -- `dotfiles/.gitconfig` - Git configuration with custom log format and vimdiff -- `dotfiles/.psqlrc` - PostgreSQL client configuration -- `dotfiles/.pspgconf` - pspg (PostgreSQL pager) configuration -- `dotfiles/bin/td` - Python CLI for time-tracking markdown todos (see Time tracking section) +Symlink-based deployment. Editing `~/.` directly edits the repo file. `git status` shows config drift. -### Custom Bash Workflow +`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. -The `.bashrc` contains a sophisticated workflow for working with: +**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 -**Database Query Management:** +**Gitignored** (machine-specific, auto-bootstrapped from examples): +- `dotfiles/.bashrc_local` — secrets and credentials +- `dotfiles/.bashrc_paths` — PATH additions and tool inits -PostgreSQL workflow: -- `xnspa()` function - Interactive file selector for running PostgreSQL queries through nvim swap files, outputs to VisiData as CSV. Accepts extra psql args (e.g. `xnspa -v var=val`). -- `xnsp` - Select and execute SQL file through fzf with pspg output -- `xns` - Select and execute SQL file through fzf -- `PG` environment variable - psql connection string to database (defined in `.bashrc_local`) +### Two-repo nvim setup -SQL Server workflow: -- `xmspa()` function - Interactive file selector for SQL Server queries through nvim swap files, outputs to VisiData with pipe-delimited format -- `xmsp` - Select SQL file via fzf, execute with sqlcmd, pipe to pspg -- `xms` - Select SQL file via fzf, execute with sqlcmd -- `MS` environment variable - sqlcmd connection string to SQL Server (defined in `.bashrc_local`) -- `MSC` environment variable - sqlcmd connection string with pipe-delimited output format (defined in `.bashrc_local`) -- `MSW` environment variable - Windows sqlcmd connection (optional, defined in `.bashrc_local`) +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 files in current directory tree +- `ons` — list open nvim swap files in current directory tree -**Git workflow aliases:** -- `gs` - git status short format -- `ga` - Interactive git add using fzf for file selection -- `gx` - Interactive git checkout using fzf -- `gr` - git reset HEAD -- `gc` - git commit verbose -- `gd` - git difftool -- `gl` - Pretty git log with colors +### 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 aliases (rg-based):** -- `td` - Find unchecked todo items using ripgrep -- `tdp` - Find priority todos (with 🔼 or ⏫) -- `tdtp` - Find top priority todos (⏫ only) -- `tdo` - Open todo in nvim at exact line -- `tdop` - Open priority todo in nvim at exact line +### Todo Grep (rg-based) +- `td` — find unchecked todos +- `tdp` / `tdtp` — priority todos (🔼 / ⏫) +- `tdo` / `tdop` — open todo in nvim at exact line -**Time tracking (functions wrapping `dotfiles/bin/td`):** -- `tstart ` - Start a timer on a task identified by a `^tid-*` block-ref -- `tstop` - Stop the running timer -- `treport [filter]` - Show totals per tid, filterable by tid or filename -- `tweek [filter]` - Show this week's time summary -- Wrappers use `command td` to bypass the `td` rg alias. The CLI writes one row per entry to `$TD_LOG` (default `./time.csv`, cwd-scoped). -- Companion nvim integration (in the separate `~/.config/nvim` repo) adds `ts/tp/tr` keymaps with auto-generated tids. +### Time Tracking +Shell wrappers around `dotfiles/bin/td` (bypasses the `td` rg alias via `command td`): +- `tstart` / `tstop` / `treport` / `tweek` -**Other useful aliases:** -- `nv` - Launch Neovim from custom installation path -- `cj` - Navigate to journal directory -- `jr` - Journal sync (pull, commit, push) -- `hc` - hc companies notes sync (pull, push) +Nvim keymaps (via `td_mappings.lua`): `ts/tp/tr/tw` -### Plugin Managers -- **Vim**: Vundle (installed to `~/.vim/bundle/Vundle.vim`) -- **Tmux**: TPM - Tmux Plugin Manager (installed to `~/.tmux/plugins/tpm`) - - Plugins: tmux-resurrect, jimeh/tmux-themepack -- **Bash**: bash-git-prompt (installed to `~/.bash-git-prompt`) +### Other Aliases +- `cj` — cd to journal +- `jr` / `hc` — sync journal / hc notes -### Package Dependencies -Base packages installed by `setup_env.sh`: -- tmux, vim, git, pspg, bat, fzf, ripgrep +## Machine-specific Configuration -## Important Conventions +`.bashrc` sources two gitignored files: -### Machine-specific configuration +- **`.bashrc_local`** — secrets: DB connection strings, passwords, tokens +- **`.bashrc_paths`** — PATH additions: nvim, cargo, nvm, java, etc. -There are two gitignored files for machine-specific configuration, both sourced by `.bashrc`: +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`. -- **`.bashrc_local`** — secrets and credentials: database connection strings, passwords, tokens. Use `dotfiles/.bashrc_local_example` as a template. -- **`.bashrc_paths`** — PATH additions and tool initializations: neovim, cargo, nvm, java, etc. Use `dotfiles/.bashrc_paths_example` as a template. +## Git Commit Style -On a new machine, copy both examples and fill them in: -```bash -cp dotfiles/.bashrc_local_example dotfiles/.bashrc_local -cp dotfiles/.bashrc_paths_example dotfiles/.bashrc_paths -``` - -When a tool (cargo, nvm, conda, etc.) auto-appends lines to `.bashrc`, `git status` will show the modification — that's your signal to move those lines to `.bashrc_paths` instead. - -### Symlink Pattern -When modifying dotfiles, remember they are symlinked. Changes are automatically tracked by git since the actual files are in the repository's `dotfiles/` directory. - -### Git Commit Messages -This repository uses simple lowercase commit messages describing the change (e.g., "add cargo", "visidata", "install sdkman"). +Simple lowercase messages: "add cargo", "visidata", "fix nv alias path" diff --git a/README.md b/README.md new file mode 100644 index 0000000..cfbf4d8 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# setup_env + +Personal Linux development environment. Clone once, run one script, get a consistent shell and editor across machines. + +## Fresh machine + +```bash +git clone git@gitea.hptrow.me:pt/setup_env.git ~/setup_env +cd ~/setup_env && ./setup_env.sh +``` + +`setup_env.sh` handles everything in order: +- Installs base packages (tmux, vim, git, fzf, ripgrep, pspg, bat) +- Downloads and installs latest Neovim to `/opt/` +- Clones TPM, Vundle, bash-git-prompt +- Deploys all dotfile symlinks +- Clones and sets up NvChad nvim config from gitea + +After install: +- **Tmux**: press `Ctrl-b + I` to install TPM plugins +- **Vim**: run `:PluginInstall` to install Vundle plugins +- Edit `dotfiles/.bashrc_local` with your real credentials (auto-created from example) +- Edit `dotfiles/.bashrc_paths` with PATH additions for tools on this machine (auto-created from example) + +## Day-to-day sync + +```bash +cd ~/setup_env && ./sync.sh +``` + +Pulls the latest setup_env and nvim config repos, redeploys all symlinks. Safe to run anytime. + +## Optional installs + +Run manually on machines that need them: + +```bash +./install_postgres.sh # PostgreSQL from official apt repository +./install_python3.sh # Latest Python 3 from deadsnakes PPA +./install_java_dev.sh # SDKMAN for Java development +./install_visidata.sh # VisiData for terminal data exploration +``` + +## Dotfile deployment + +All config files are symlinked, not copied — editing `~/.` edits the repo file directly. `git status` always shows config drift. + +| Source | Deployed to | Notes | +|---|---|---| +| `dotfiles/.bashrc` | `~/.bashrc` | Main shell config | +| `dotfiles/.bashrc_local` | `~/.bashrc_local` | Secrets/credentials — gitignored | +| `dotfiles/.bashrc_paths` | `~/.bashrc_paths` | PATH and tool inits — gitignored | +| `dotfiles/.vimrc`, `.gitconfig`, `.tmux.conf`, etc. | `~/` | Standard dotfiles | +| `dotfiles/bin/*` | `~/.local/bin/` | Executable scripts | +| `dotfiles/nvim/*.lua` | `~/.config/nvim/lua/` | Nvim lua modules | + +When a tool appends lines to `.bashrc`, `git status` shows the modification — move those lines to `.bashrc_paths` instead. + +## Machine-specific config + +Two gitignored files sourced by `.bashrc`, auto-bootstrapped from examples on first run: + +- **`.bashrc_local`** — DB connection strings, passwords, tokens +- **`.bashrc_paths`** — PATH additions (nvim, cargo, nvm, java, etc.) + +--- + +## td — markdown todo time tracking + +Track time on markdown todos identified by a block-ref `^tid-*`. Data lives in `time.csv` at the vault root. + +### Surfaces + +| Surface | Location | How to use | +|---|---|---| +| CLI | `bin/td` → `~/.local/bin/td` | `command td ` | +| Shell wrappers | `.bashrc` | `tstart`, `tstop`, `treport`, `tweek` | +| Nvim | `nvim/td.lua` + `nvim/td_mappings.lua` | `ts/tp/tr/tw` or `:TdStart/Stop/Report/Week` | + +### Subcommands + +| Command | What it does | +|---|---| +| `td start [--file PATH] [--desc TEXT]` | Start timer, auto-stops any running entry | +| `td stop` | Close the open entry | +| `td report [filter]` | Total time per tid (filter matches tid or file) | +| `td week [--since DATE]` | Tasks from git log joined with time data | +| `td current` | Print the currently-running tid | +| `td tidgen` | Generate a fresh tid | + +### How `td week` works + +Scans `git log -p` from cwd, pairs `-`/`+` task-line diffs within each commit by tid: + +- `[x]` **done** — `- [ ]` → `- [x]` transition +- `[ ]` **new** — added `- [ ]` line with a fresh tid +- `[+]` **done+new** — created and completed in the same commit +- `[o]` **reopen** — `- [x]` → `- [ ]` transition + +### Nvim integration + +`ts` on a `- [ ]` line auto-generates a `^tid-*` block ref if missing, saves the buffer, and starts the timer. `tp` stops, `tr` shows a report float, `tw` shows the week float. Close floats with `q` or ``. + +### Gotchas + +- **`td` alone is aliased to `rg`** for todo-grepping. Use `tweek`, `treport` etc. or `command td` to reach the CLI directly. +- **CSV is cwd-scoped.** Run subcommands from the vault root. The nvim wrapper walks up to find it; shell wrappers trust your cwd. +- **Data-model changes go in `bin/td`.** Shell and nvim surfaces stay thin wrappers. diff --git a/dotfiles/README.md b/dotfiles/README.md deleted file mode 100644 index 72e96a9..0000000 --- a/dotfiles/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# dotfiles - -Symlink-deployed config. The parent `~/setup_env/setup_env.sh` installs each file here to its destination path — edit the file in this repo, the change goes live. - -| Source in this repo | Deployed to | Deployed by | -| --- | --- | --- | -| `.bashrc`, `.vimrc`, `.gitconfig`, `.pspgconf`, `.psqlrc`, `.tmux.conf`, `.bashrc_local` | `~/` | `deploy_configs` | -| `bin/*` | `~/.local/bin/` | `deploy_bin` | -| `nvim/*.lua` | `~/.config/nvim/lua/.lua` | `deploy_nvim` | - -On a fresh machine: clone the `setup_env` repo, then from `~/setup_env/` run: - -```bash -./install_neovim.sh -./install_nvchad.sh -./install_python3.sh -./setup_env.sh # creates all the symlinks + installs apt packages -``` - -After install you still need to add one line to the NvChad-provided `~/.config/nvim/lua/mappings.lua` (it's not tracked here because NvChad owns that file): - -```lua -require("td_mappings") -``` - -Everything else picks up automatically. - ---- - -## td — markdown todo time tracking - -Track time on markdown todos identified by an Obsidian block-ref `^tid-*` at the end of the task line. Data lives in `time.csv` at the vault root; reports cross-join time with git history to show what was created vs. completed. - -### The three surfaces (one script) - -All logic is in `bin/td` — a Python 3 stdlib script. The other surfaces are thin wrappers so the script is reachable from each editing context. - -| Surface | Location | Purpose | -| --- | --- | --- | -| Python script | `bin/td` → `~/.local/bin/td` | Single source of truth. All subcommands. | -| Shell wrappers | `.bashrc` (`tstart` / `tstop` / `treport` / `tweek`) | Bypass the `td` alias (see gotcha). | -| Nvim module | `nvim/td.lua` + `nvim/td_mappings.lua` | `:TdStart` / `:TdStop` / `:TdReport` / `:TdWeek` commands + `t{s,p,r,w}` keymaps. | - -### Data model - -`time.csv` at the vault root: - -``` -started_at, stopped_at, tid, file, description -``` - -- `tid` — block-ref identifier, format `tid-YYYYMMDD-HHMMSS`, appended as `^tid-...` to the task line in the markdown file -- `started_at` / `stopped_at` — ISO-8601 local timestamps; a running entry has an empty `stopped_at` -- one row per time segment; `td stop` fills in `stopped_at` on the open row - -Vault root is discovered by walking up from the current buffer file looking for `time.csv` or `.obsidian/`. - -### Subcommands - -| Command | What it does | -| --- | --- | -| `td start [--file PATH] [--desc TEXT]` | Start a timer. Auto-stops any running entry first. If `--file` / `--desc` aren't given, greps the vault for the tid to populate them. | -| `td stop` | Close the open entry. | -| `td report [FILTER]` | Total time per tid (filter matches tid or file substring). | -| `td current` | Print the currently-running tid (or nothing). | -| `td tidgen` | Print a fresh `tid-YYYYMMDD-HHMMSS`. | -| `td week [--since DATE]` | Task create/complete events from `git log -p`, joined with `time.csv`. Default range: since Monday 00:00 of this week. | - -### How `td week` works - -Scans `git log -p --reverse --no-renames` from cwd, pairs `-`/`+` task-line diffs within each commit by tid, classifies each event: - -- `[x]` **done** — `- [ ]` → `- [x]` transition in one commit -- `[ ]` **new** — added `- [ ]` line with a fresh tid -- `[+]` **done+new** — `- [x]` added with no prior `- [ ]` for that tid (created and completed in the same commit) -- `[o]` **reopen** — `- [x]` → `- [ ]` transition - -Event timestamp is commit time, not toggle time — batched commits share one timestamp. Fine for weekly "what did I get done" reports; not precise enough for hourly auditing. - -### Nvim integration - -`ts` / `:TdStart` on a `- [ ]` task line: -1. If the line has no `^tid-*` block ref, auto-generates `tid-YYYYMMDD-HHMMSS`, appends it, saves the buffer. -2. Starts the timer with the file path (relative to vault root) and the task text (minus checkbox + block ref) as description. - -Other mappings: `tp` stop, `tr` report float, `tw` week float. `q` or `` closes a float. - -Known limitation: NvChad defers `mappings.lua` via `vim.schedule`, so `:TdStart` etc. aren't available inside `-c` arguments on headless invocations. Interactive use is fine. - -### Gotchas - -- **`td` alone is aliased to `rg`** (for the `td` / `tdp` / `tdo` todo-grep family, defined in `.bashrc`). So `td week` runs `rg "\- \[[^(x|~)]\]" week` and errors out. Use `tweek` (shell wrapper that calls `command td week`) or `command td week` directly. -- **CSV is cwd-scoped.** `$TD_LOG` defaults to `./time.csv`, so subcommands must be run from (or under) the vault root. The nvim wrapper handles this by walking up to find the vault root; the shell wrappers trust your cwd. -- **Data-model changes go in `bin/td`.** The shell and nvim surfaces should stay thin — if a new subcommand is useful in nvim too, add it to `bin/td`, then a one-line `tfoo()` wrapper in `.bashrc` and a `M.foo` + mapping in `nvim/td.lua` / `nvim/td_mappings.lua`.