Repository navigation
Fix exponential backtracking in typescriptArrowFuncDef - #306
Merged
HerringtonDarkholme merged 2 commits intoSep 29, 2026
Merged
HerringtonDarkholme merged 2 commits into
HerringtonDarkholme merged 2 commits into
Conversation
The paren-based typescriptArrowFuncDef patterns contain a nested quantifier, \%(\_[^()]\+\|...\)*, which backtracks exponentially with the old regexp engine when the match fails. Drop the inner \+; the matched language is unchanged. Refs HerringtonDarkholme#135 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
|
Thanks! |
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The regex transformation preserves the accepted language, removes ambiguous nested repetition, and is consistently propagated to generated files.
Review effort: Balanced
Findings: None
What changed in this PR
Removes exponential backtracking from TypeScript arrow-function syntax matching while preserving highlighting behavior.
Changes:
- Replaces nested quantified character runs with deterministic single-character repetition.
- Synchronizes all generated TypeScript syntax bundles.
| File | Description |
|---|---|
syntax/ts-common/function.vim |
Optimizes both parenthesized arrow-function patterns. |
merged/typescriptreact.vim |
Updates the generated TSX syntax bundle. |
merged/typescriptcommon.vim |
Updates the generated common syntax bundle. |
merged/typescript.vim |
Updates the generated TypeScript syntax bundle. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
HerringtonDarkholme
approved these changes
Sep 29, 2026
HerringtonDarkholme
merged commit Sep 29, 2026
a7ad165
into
HerringtonDarkholme:master
2 checks passed
Contributor
Author
|
Thanks for the quick merge! Sent the same change to Vim's runtime: vim/vim#21400 |
chrisbra
pushed a commit
to vim/vim
that referenced
this pull request
Sep 29, 2026
…uncDef
Problem: The paren-based typescriptArrowFuncDef patterns contain a nested
quantifier, \%(\_[^()]\+\|...\)*, which backtracks exponentially
with the old regexp engine when the match fails.
Solution: Drop the inner \+; the matched language is unchanged.
closes: #21400
related: HerringtonDarkholme/yats.vim#306
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Miura Yasuyuki <kokosabu@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
zeertzjq
added a commit
to neovim/neovim
that referenced
this pull request
Sep 30, 2026
…in typescriptArrowFuncDef
Problem: The paren-based typescriptArrowFuncDef patterns contain a nested
quantifier, \%(\_[^()]\+\|...\)*, which backtracks exponentially
with the old regexp engine when the match fails.
Solution: Drop the inner \+; the matched language is unchanged.
closes: vim/vim#21400
related: HerringtonDarkholme/yats.vim#306
vim/vim@bb1d7bc
Co-authored-by: Miura Yasuyuki <kokosabu@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The two paren-based
typescriptArrowFuncDefpatterns insyntax/ts-common/function.vimcontain a nested quantifier:\%(\_[^()]\+\|...\)*is the classic(a+)*shape. When the pattern fails(a parenthesized call argument list that is not followed by
=>/):), thebacktracking engine tries every way to split the run of non-paren characters,
so matching time doubles with each extra character. This PR drops the inner
\+. The alternation still matches exactly the same strings, but thebacktracking becomes linear.
Related: #135 (same symptom, same shape of reproducer).
Reproduction
Vim with
regexpengine=1(this is the default of the Vim bundled with macOS,see vim/vim#18782), no vimrc:
Vim hangs and eventually reports
'redrawtime' exceeded, syntax highlighting disabled. The time roughly doubles per character inside the parens(0.78s -> 2.6s -> 10.6s on macOS Vim 9.1 as the argument list grows by two
characters per step).
Verification
Built Vim from master (9.2, patches 1-1143) with its own runtime, ran
synID()over every line of the reproducer and of a ~490-line TypeScript file:re=0re=1re=2Highlighting is unchanged: I dumped
synstack()names for every characterposition (14,543 positions, including 116 inside
typescriptArrowFuncDeffromarrow functions with typed params, defaults, nested parens, generics and
arrow functions inside ternaries / call arguments). The dumps before and after
the change are identical (
diffshows no differences).The test suite that CI runs (
Vader! syntax.vader tsx.vaderintest/)passes locally with this change: 149/149 (457 assertions) on macOS Vim 9.1.
I have not run it on Neovim.
merged/is regenerated withnode merge.js. Its only changes are the sametwo lines in each of the three files.
The same patterns also exist in Vim's
runtime/syntax/shared/typescriptcommon.vim, lines 1951 and 1956. I can sendthe same change to vim/vim after this is merged.
🤖 Generated with Claude Code