td week parses git log for task create/complete events and joins with time.csv for weekly "what got done" reports. Nvim integration moved into dotfiles/nvim/ (symlinked in by new deploy_nvim step) so all three td surfaces live under dotfiles. README covers the deploy pattern and td. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
95 lines
4.9 KiB
Markdown
95 lines
4.9 KiB
Markdown
# 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` | `~/<filename>` | `deploy_configs` |
|
|
| `bin/*` | `~/.local/bin/<name>` | `deploy_bin` |
|
|
| `nvim/*.lua` | `~/.config/nvim/lua/<name>.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 + `<leader>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 <tid> [--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
|
|
|
|
`<leader>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: `<leader>tp` stop, `<leader>tr` report float, `<leader>tw` week float. `q` or `<Esc>` 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`.
|