Commit Graph
13 Commits
Author SHA1 Message Date
swaitsandClaude Opus 4.7 cbc54ba685 chore(release): 0.4.0
CI / check / clippy / fmt (push) Canceled after 0s
CI / build (1.85) (push) Canceled after 0s
CI / build (stable) (push) Canceled after 0s
Restores `jj show` support, broken by the 0.3.0 dispatch rewrite.
`jj show` accepts its revision as a positional `[REVSET]` argument
rather than a `-r` option, which the help-driven dispatch didn't
recognize — so bare `jjf` (which defaults to `show`) errored instead
of opening the picker. A revision named as a bare positional now also
bypasses the picker, like an explicit `-r`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.4.0
2026-05-22 13:58:43 -06:00
swaitsandClaude Opus 4.7 7390b92a40 fix(dispatch): detect jj show's positional revset argument
The 0.3.0 help-driven dispatch only scanned a leaf's `Options:` block
for a revset flag. `jj show` takes its revision as a positional
`[REVSET]` argument, not an option, so it looked like it accepted no
revset — and bare `jjf` (which defaults to `show`) errored with
"takes no revset flag" instead of opening the picker.

- Read the `Arguments:` block too: a positional `[REVSET]`/`[REVSETS]`
  that exposes `-r` as an alias is recognized, and jjf injects
  `-r <picked>` for it.
- A bare positional in the passthrough now counts as the user having
  named the revision, so `jjf show @-` bypasses the picker like an
  explicit `-r` would. Option values are stepped over (parsing every
  `Options:` section, including globals) so they aren't mistaken for
  the positional.
- The picker-bypass check also accepts the inline `--revision=<rev>` /
  `--to=<rev>` form, not just space-separated flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:58:00 -06:00
swaits 40a83b388a chore(release): 0.3.0
Subcommand dispatch is now help-driven instead of substring-matching
"REVSET", so multi-level subcommands (`tag set`, `bookmark move`, …)
and non-`-r` revset flags (`--to`) work, and pre-supplied revset
flags bypass the picker instead of being double-injected.
v0.3.0
2026-05-04 12:58:47 -06:00
swaits 6ce9cb2b17 feat(dispatch): walk subcommands and detect revset flag from help
Two real failures motivated this:

- `jjf bm main` (where `bm` is a user alias for `bookmark move`) ran
  `jj bm main -r <id>` — but bookmark move uses `--to`, not `-r`.
- `jjf tag set v0.2.0` errored with "doesn't take revisions" because
  jjf only inspected `jj tag --help` (parent) instead of walking
  into the `set` leaf, which does take `-r`.

Replace the boolean `supports_revisions()` (a substring match on
"REVSET") with `RevsetTarget { leaf, passthrough, flag }`:

- Walks multi-level subcommands by parsing each parent's `Commands:`
  block — including `[aliases: …]` annotations, so `jjf tag s` walks
  to `tag set`. Aliases like `bm` work transparently because `jj bm
  --help` already emits the resolved leaf's help.
- Parses the leaf's `Options:` block and picks the revset flag in
  priority order: `-r`/`--revision[s]` first, then `-t, --to`.
  `--from` is intentionally not a fallback (different semantics from
  "the revision the picker chose").
- Bypasses the picker entirely when the user already passed a revset
  flag in their args, so `jjf describe -r @-` runs verbatim instead
  of double-injecting `-r`.

`exec` and `command_line` now take `&RevsetTarget` and emit the
resolved flag; signatures thread through `tui.rs` and `main.rs`.

New unit tests cover the help parsers and command-line construction
against captured fixtures of `jj tag set --help`, `jj bookmark move
--help`, and `jj tag --help`.
2026-05-04 12:58:14 -06:00
swaitsandClaude Opus 4.7 1c4ae09646 chore(release): 0.2.0
Picker now renders jj's real graph (merge connectors and all). Cursor
and filter skip decorative connector rows; hint row drops trailing
key/label pairs to fit a single line on narrow terminals; cursor
arrow glyphs changed to ●──▶.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.2.0
2026-04-29 23:38:20 -06:00
swaits 3b63d67737 chore(release): 0.1.0
- Add LICENSE (MIT, copyright 2026 Stephen Waits)
- Add README.md reflecting the current TUI: two-column preview pane
  with jj show --summary, live command preview row, default-to-show
  behavior, full keybinding table, shell integration matrix, internals
  overview, attribution to oppi.li's original bash+fzf concept
- Add CHANGELOG.md (keep-a-changelog format) with 0.1.0 release notes
- Add .github/workflows/ci.yml — fmt + clippy + check on every push/PR;
  build matrix on stable + 1.85 (MSRV)
- Update Cargo.toml: refined description, repository/homepage/docs
  URLs, keywords + categories, rust-version=1.85, exclude .github and
  ux.txt from the published tarball
- Update .gitignore to also exclude ux.txt (scratch UX mockup)

Verified clean:
  cargo fmt --all -- --check
  cargo clippy --all-targets -- -D warnings
  cargo publish --dry-run --allow-dirty  (16 files, 20.6 KiB compressed)
v0.1.0
2026-04-29 19:49:11 -06:00
swaits d2740008e9 feat(ux): more refinements
- Custom oneline template (drops timestamp + commit-id hash from the
  left pane); keeps change-id with shortest-unique-prefix highlighting,
  bookmarks, conflict/empty labels, and the description first-line.
  More room for the actually-useful columns.
- Drop the dim '── <change_id> ────' header above the preview; the
  cursor row tee (├) now carries the 'this is what you're looking at'
  signal.
- Box-char frame for the preview pane: top border (┌────) and left
  border (│), with ├ replacing │ on the cursor row to draw the eye
  from picker selection into preview content.
- Dynamic description clipping: the description fills whatever rows
  are left after the file list (ellipsis on overflow). Replaces the
  hard 3-line cap, which under-used vertical space for short file
  lists and was buggy (didn't count blank lines within description).
- Bump VIEWPORT_MIN from 15 to 20 so the preview pane has enough
  vertical room to be useful by default.
2026-04-29 18:12:40 -06:00
swaits 8605528960 feat(ux): batch UX improvements
- Reverse-video caret in input row (was cyan █ block — collided with
  the cyan ❯ prompt and read as 'unfocused-pane cursor')
- Synchronized-output brackets (DEC mode 2026) around each redraw —
  eliminates tearing on Kitty/WezTerm/foot/recent iTerm; ignored elsewhere
- Two-tone hint row (keys at normal weight, labels dim) gives the eye
  a scan anchor
- Dim header above preview pane (── <change_id> ────) anchors the right
  column to the cursor row's revision
- Light-terminal detection via COLORFGBG: switch cursor-row highlight
  from indexed-237 dark-gray bg to reverse-video on themes where the
  dark bg would be invisible
- Shell wrappers echo the resolved 'jj …' command (dim '$' prefix)
  before running it, so it's visible in scrollback
2026-04-29 16:29:01 -06:00
swaits 5650a14d55 fix(history): drop jjf entry on cancel/error paths too
Previously, the original `jjf …` invocation only got dropped from
history on successful confirm. A cancelled or errored picker left a
useless `jjf …` entry behind. Now bash drops it unconditionally via
`_jjf_drop_last_history`; fish arms the postexec hook before the
`--emit` call so the deletion happens regardless of exit path.
2026-04-29 16:20:57 -06:00
swaits 6479867e61 feat: two-column layout with jj show preview pane
When term_cols >= 80, right side shows jj show --summary of the
currently highlighted revision (header stripped — just description and
the M/A/D file list, with description capped at 3 lines). Per-row
preview is cached, so navigating back to previously-viewed revs is
instant. Bumps the viewport floor to 15 rows (max = full terminal) so
the preview has room to be useful.
2026-04-29 16:20:57 -06:00
swaits 7dec6770cc feat: default to 'show' subcommand when jjf is invoked without args
Mirrors the original bash+fzf script's behavior — `jjf` alone becomes
a quick rev browser. Implemented in shell wrappers (so the --emit
history-rewrite path still applies); the binary itself still prints
usage on bare invocation, for explicit invocations.
2026-04-29 15:58:55 -06:00
swaits 3d0ba30bfc feat: broaden picker revset to all() to expose every operable revision
Previously used jj's default revsets.log, which is intentionally narrow
for jj log's scrollback purposes (`@ | trunk() | ancestors(mutable, 2)`).
For a picker, we want every visible revision so older revs (for abandon,
rebase -d, etc.) are reachable. `--limit 1000` keeps the blast radius
bounded on huge repos; smart prefix matching keeps lookup cheap.
2026-04-29 15:58:55 -06:00
swaits ed801c80ee feat: initial implementation of jjf
A TUI revision picker for jujutsu (jj). Wraps any jj subcommand with an
inline fuzzy-finder over jj log, then forwards the picked revision(s)
as -r '<id>' to the underlying jj invocation.

Features:
- Inline viewport (no full-screen alt-screen takeover)
- Smart prefix matching: typing the bold portion of a change ID jumps
  to that revision instantly
- Multi-select via Tab; emitted as -r 'A|B|C' revset union
- Preflight detection of subcommands that don't accept -r
- Optional shell integration (jjf init <bash|zsh|fish|nu>) that
  rewrites shell history so up-arrow recalls the resolved jj command

Hand-rolled ANSI rendering to /dev/tty; only crossterm, nucleo-matcher,
anyhow, and libc as runtime dependencies.
2026-04-29 15:58:55 -06:00