Post-merge follow-ups for #2740 #2735 #2734 #2690 #2676 #2738 #2684 #2689 #2733 #2739 #2462 #2687 #2736 #2618 #2697, plus three regressions found while reviewing them: - ctrl/cmd+digit while typing no longer switches session tabs (#2503 was still open in practice: the guard only covered the mod+alt surface binding) - Shiki template-call sanitizer now covers every bundled grammar, including the js/ts aliases and embedding grammars; timed-out highlight requests are memoized and no longer cancel unrelated in-flight requests - settings flush on suspend uses keepalive and also fires on Capacitor appStateChange; keeps the selected model persisted across mode switches - remote-only branches fetch before checkout; range helpers fail clearly - git status invalidation now fires for runtime adapters too - settings number inputs and select triggers size in ch so they scale with the interface font - recent-activity timestamps tick from one list-level ticker - Markdown preview find goes through the shared find_in_file keybind with containment, no longer counts its own bar, and debounces observer runs - #2676 reverted; #2524 fixed by fading the sticky header's own background instead of overlaying the content below it - sticky group headers in the model picker and sidebar render again (oc-sticky-fade-scroller class restored after9b9d7069c) - project switcher names are left-aligned again (wrapper lost in26dbc2f30) - tool card quick-open icon is always visible and opens the same line as the expanded card's button - tautological tests replaced or removed; new oxlint findings fixed
38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
/**
|
|
* Neutralize the JavaScript/TypeScript TextMate `template-call` rule.
|
|
*
|
|
* Upstream grammars use a triple-nested `{()[]}` lookahead to detect tagged
|
|
* templates with type arguments (`foo<T>\`...\``). On the Oniguruma WASM engine
|
|
* shipped with Shiki — which does not expose `setRetryLimit` / match-stack
|
|
* limits — that pattern can enter exponential backtracking on ordinary
|
|
* backtick template literals, grow the WASM heap without bound, and OOM the
|
|
* renderer (openchamber/openchamber#2587).
|
|
*
|
|
* Clearing `template-call` is safe: the plain `#template` rule still highlights
|
|
* backticks and simple tagged templates. Only the rare `ident<TypeArgs>\`...\``
|
|
* form loses its specialized type-argument coloring and falls through to
|
|
* normal tokenization.
|
|
*/
|
|
|
|
type GrammarRepository = Record<string, { patterns?: unknown[] } | undefined>;
|
|
|
|
export type TemplateCallGrammar = {
|
|
name?: string;
|
|
repository?: GrammarRepository;
|
|
};
|
|
|
|
const TEMPLATE_CALL_KEY = 'template-call';
|
|
|
|
export const hasCatastrophicTemplateCall = (grammar: TemplateCallGrammar): boolean => {
|
|
const patterns = grammar.repository?.[TEMPLATE_CALL_KEY]?.patterns;
|
|
return Array.isArray(patterns) && patterns.length > 0;
|
|
};
|
|
|
|
export const sanitizeTemplateCallGrammar = <T extends TemplateCallGrammar>(grammar: T): T => {
|
|
if (!hasCatastrophicTemplateCall(grammar)) return grammar;
|
|
|
|
const repository = { ...grammar.repository };
|
|
repository[TEMPLATE_CALL_KEY] = { patterns: [] };
|
|
return { ...grammar, repository };
|
|
};
|