Fix terminal path detection inside parentheses#52222
Fix terminal path detection inside parentheses#52222Veykril merged 5 commits intozed-industries:mainfrom
Conversation
|
We require contributors to sign our Contributor License Agreement, and we don't have @butvinm on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
| #[test] | ||
| #[should_panic(expected = "Path = «copy).yml»")] | ||
| // Filenames with parentheses in the middle (e.g. `file(copy).txt`) are not | ||
| // matched as a single path because `(` is treated as a path boundary. This is | ||
| // a tradeoff to support the more common `Tool(path)` pattern (e.g. Claude Code | ||
| // output like `Update(.claude/SKILL.md)`) where `(` is a delimiter, not part | ||
| // of the filename. | ||
| fn parens_in_filename_not_matched() { | ||
| test_path!("‹«docker-compose.prod(👉copy).yml»›"); | ||
| } |
There was a problem hiding this comment.
This isn't really an acceptable tradeoff. Some folks tend to have usernames with parentheses inside which breaks especially on Windows systems
There was a problem hiding this comment.
I overlooked that it might be a common use case.
I implemented detection of such file paths following sanitize_url_punctuation logic. Now paths like /tmp/test(copy).txt are clickable.
Paths inside parentheses without a preceding space (e.g. `Update(path)` or `Write(path)` from Claude Code output) were not clickable because `(` was allowed as a middle character in the path regex, causing the entire `Update(.path/here` to be matched as a single (invalid) path. Two changes: - Remove `(` from the middle-chars alternation in the default path hyperlink regex so `(` always acts as a path boundary (consistent with it already being excluded from first/last chars). Preserve upstream's space exclusion after `:`. - Iterate all regex matches in the line instead of only the first, so the correct path (the second match) is found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Filenames with parentheses in the middle (e.g. `file(copy).txt`) are no longer matched as a single path because `(` is now treated as a path boundary. Document this known limitation with a should_panic test. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Paths inside parentheses without a preceding space (e.g. `Update(path)` from Claude Code output) were not clickable because the regex matched the entire `Update(.path/here` as a single invalid path. Instead of removing `(` from the regex (which would break filenames with parentheses like `file(copy).txt` or Windows usernames), add a balanced-parentheses post-processing step: when the matched path contains more `(` than `)`, strip the prefix up to the first unmatched `(`. This mirrors `sanitize_url_punctuation` which strips unbalanced trailing `)` from URLs. Also iterate all regex matches in the line instead of only the first, so paths that appear after other words are found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Head branch was pushed to by a user without write access
d429c11 to
7561759
Compare
|
@kubkon would you have a chance to look at this PR? |
Summary
Paths inside parentheses without a preceding space (e.g.
Update(.claude/skills/sandbox/SKILL.md)orWrite(/test/cool.rs)from Claude Code output) were not clickable in the terminal. The(character was allowed as a middle character in the default path hyperlink regex, causing the entireUpdate(.path/hereto be matched as a single invalid path.Changes:
(from the middle-chars alternation ([:(]→:) in the default path hyperlink regex, so(always acts as a path boundary — consistent with it already being excluded from first and last character sets. Preserves upstream's space exclusion after:.Update) is found. This also simplifies the code by removing the separate hovered-word search logic.Known tradeoff:
Filenames with parentheses in the middle (e.g.
docker-compose.prod(copy).yml) are no longer matched as a single path. This is uncommon in terminal output contexts (compiler errors, stack traces, tool output) and is documented with ashould_panictest.What doesn't break:
(/path/file.js:321:13)—(at word start is excluded by the first-char rule (unchanged)at fn (/path/file.js:10:5)— space before(makes it a separate wordRelated: #18556, #23774
Release Notes:
Update(path)orWrite(path)patterns from CLI tool output)