in src/grammar.ts [686:757]
function handleCaptures(grammar: Grammar, lineText: OnigString, isFirstLine: boolean, stack: StackElement, lineTokens: LineTokens, captures: (CaptureRule | null)[], captureIndices: IOnigCaptureIndex[]): void {
if (captures.length === 0) {
return;
}
const lineTextContent = lineText.content;
const len = Math.min(captures.length, captureIndices.length);
const localStack: LocalStackElement[] = [];
const maxEnd = captureIndices[0].end;
for (let i = 0; i < len; i++) {
const captureRule = captures[i];
if (captureRule === null) {
// Not interested
continue;
}
const captureIndex = captureIndices[i];
if (captureIndex.length === 0) {
// Nothing really captured
continue;
}
if (captureIndex.start > maxEnd) {
// Capture going beyond consumed string
break;
}
// pop captures while needed
while (localStack.length > 0 && localStack[localStack.length - 1].endPos <= captureIndex.start) {
// pop!
lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, localStack[localStack.length - 1].endPos);
localStack.pop();
}
if (localStack.length > 0) {
lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, captureIndex.start);
} else {
lineTokens.produce(stack, captureIndex.start);
}
if (captureRule.retokenizeCapturedWithRuleId) {
// the capture requires additional matching
const scopeName = captureRule.getName(lineTextContent, captureIndices);
const nameScopesList = stack.contentNameScopesList.push(grammar, scopeName);
const contentName = captureRule.getContentName(lineTextContent, captureIndices);
const contentNameScopesList = nameScopesList.push(grammar, contentName);
const stackClone = stack.push(captureRule.retokenizeCapturedWithRuleId, captureIndex.start, -1, false, null, nameScopesList, contentNameScopesList);
const onigSubStr = grammar.createOnigString(lineTextContent.substring(0, captureIndex.end));
_tokenizeString(grammar, onigSubStr, (isFirstLine && captureIndex.start === 0), captureIndex.start, stackClone, lineTokens, false, /* no time limit */0);
disposeOnigString(onigSubStr);
continue;
}
const captureRuleScopeName = captureRule.getName(lineTextContent, captureIndices);
if (captureRuleScopeName !== null) {
// push
const base = localStack.length > 0 ? localStack[localStack.length - 1].scopes : stack.contentNameScopesList;
const captureRuleScopesList = base.push(grammar, captureRuleScopeName);
localStack.push(new LocalStackElement(captureRuleScopesList, captureIndex.end));
}
}
while (localStack.length > 0) {
// pop!
lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, localStack[localStack.length - 1].endPos);
localStack.pop();
}
}