gh and glab both accept several subcommands without an explicit id and
resolve it from the current branch (gh pr view, gh pr checks, glab mr
view) or open an interactive picker (gh run view). RTK was pre-rejecting
with "X number required" before the underlying tool ever ran.
Six call sites now treat the identifier as optional and forward the
request unchanged, letting gh/glab decide:
- gh pr view, gh pr checks, gh issue view, gh run view
- glab mr view, glab issue view
A new `parse_optional_identifier` helper in each file captures the
"(Option<id>, Vec<extra>)" parse so the no-id branch is unit-testable.
format_run_view also drops the dangling `#` from its header when the
run id is empty (interactive-picker passthrough).
Closes#1564.
`rtk hook check` rejected commands that began with a bash line
continuation (`\<NL>`) because the matcher saw the literal `\`
as the first token and bailed out:
$ rtk hook check $'\\\ngit diff HEAD~1'
No rewrite for: \\ngit diff HEAD~1
Bash collapses `\<NL>` (and `\<CRLF>`) plus surrounding horizontal
whitespace to a single space before dispatching the command, so
the matcher should do the same. Internal continuations (e.g.
`git diff \<NL>HEAD~1`) are equally common when Claude Code
formats long invocations.
Add a small `collapse_line_continuations` helper that runs a
single regex over the input before `cmd.trim()`. The regex eats
the trailing whitespace on the previous line and the leading
indentation on the next line so the no-double-space invariant
holds. The fast path returns `Cow::Borrowed` when no continuation
is present, so commands without `\<NL>` allocate nothing.
Six regression tests pin: leading \\<NL\>, leading \\<CRLF\>, internal
\\<NL\> between subcommand and args, \\<NL\> followed by indentation,
the no-op fast path, and the helper-level Cow::Borrowed contract.
- rg: switch to `-nH --null` for robust file/content separation
- grep fallback: switch to `-rnHZ` to match rg's --null contract
- Parser regex: `^([^\x00]+)\x00(\d+):(.*)$` so filenames or content
containing `:digits:` (e.g. `badly_named:52:file.txt`,
`debug: counter is :42: now`) can no longer fool the parser
- Use `Captures::extract` for cleaner destructuring
Adds tests for the badly-named-filename and digit-colons-in-content
cases; updates existing tests to use NUL-separated fixtures.
Addresses review on #1554.
Signed-off-by: Artiom Tofan <arto@queue-it.com>
Single-file `rtk grep` returned synthetic `[file] N` buckets when a
matching line contained `:`. ripgrep emits `<line>:<content>` for
single-file searches; the parser used `splitn(3, ':')` length to
disambiguate, which fails when content has `:` (e.g. `Foo::bar(...)`).
Force `--with-filename` on rg (`-H` on the grep fallback) so output is
always `file:line:content`, and replace the inline parser with a
regex-based `parse_match_line` that also handles paths with embedded
`:` (Windows drive letters).
Fixes the parser/rendering portion of #1436. The BRE-translation
portion is addressed in a follow-up PR.
Signed-off-by: Artiom Tofan <arto@queue-it.com>
The compact `git status` path ran `git status --porcelain -b -uall`. The
`-uall` flag expands fully-untracked directories into every file, while raw
`git status` collapses them (e.g. `node_modules/`). This made rtk output
larger than raw — measured ~29x on a 200-file untracked dir (5500B vs 191B) —
violating RTK's compress-or-match-raw invariant and inflating tokens.
Remove `-uall` so untracked directories collapse exactly like raw. This keeps
#991's actual fix intact: all modified/staged/renamed/conflict paths are still
shown with no grouped summaries or `... +N more` overflow markers (`-uall`
never affected those lines). Untracked files in partially-tracked dirs and any
paths git itself expands are still preserved by the formatter.
Measured (rtk vs raw git status):
- node_modules/ (200 files): 5500B (-2780%) -> 25B (+87% savings)
- normal (8 mod + 2 untracked): +71% -> +76%
- 17 modified (#991 case): unchanged at +58%, all 17 shown, 0 overflow markers
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>