boolean (@NotNull Queue<Token> output, Constants.CaptureKey captureKey, SyntaxNodeDescriptor rule, MatchData matchData, StringWithId string, CharSequence line, int startLineOffset, FList<TextMateLexerState> states) { TextMateCapture @Nullable [] captures = rule.getCaptureRules(captureKey); if (captures == null) { return false; } Deque<TextMateRange> activeCaptureRanges = new LinkedList<>(); for (int group = 0; group < matchData.count(); group++) { TextMateCapture capture = group < captures.length ? captures[group] : null; if (capture == null) { continue; } TextMateRange byteRange = matchData.byteOffset(group); if (byteRange.isEmpty()) { continue; } TextMateRange captureRange = matchData.charRange(line, string.bytes, group); while (!activeCaptureRanges.isEmpty() && activeCaptureRanges.peek().end <= captureRange.start) { closeScopeSelector(output, startLineOffset + activeCaptureRanges.pop().end); } if (capture instanceof TextMateCapture.Name) { CharSequence captureName = ((TextMateCapture.Name)capture).getName(); CharSequence scopeName = rule.hasBackReference(captureKey, group) ? SyntaxMatchUtils.replaceGroupsWithMatchDataInCaptures(captureName, string, matchData) : captureName; int selectorStartOffset = 0; int indexOfSpace = Strings.indexOf(scopeName, ' ', selectorStartOffset); if (indexOfSpace == -1) { openScopeSelector(output, scopeName, startLineOffset + captureRange.start); activeCaptureRanges.push(captureRange); } else { while (indexOfSpace >= 0) { openScopeSelector(output, scopeName.subSequence(selectorStartOffset, indexOfSpace), startLineOffset + captureRange.start); selectorStartOffset = indexOfSpace + 1; indexOfSpace = Strings.indexOf(scopeName, ' ', selectorStartOffset); activeCaptureRanges.push(captureRange); } openScopeSelector(output, scopeName.subSequence(selectorStartOffset, scopeName.length()), startLineOffset + captureRange.start); activeCaptureRanges.push(captureRange); } } else if (capture instanceof TextMateCapture.Rule) { CharSequence capturedString = line.subSequence(0, captureRange.end); StringWithId capturedStringWithId = new StringWithId(capturedString); TextMateLexerState captureState = new TextMateLexerState(((TextMateCapture.Rule)capture).getNode(), matchData, TextMateWeigh.Priority.NORMAL, byteRange.start, capturedStringWithId); parseLine(capturedString, output, states.prepend(captureState), startLineOffset, captureRange.start, byteRange.start); } else { throw new IllegalStateException("unknown capture type: " + capture); } } while (!activeCaptureRanges.isEmpty()) { closeScopeSelector(output, startLineOffset + activeCaptureRanges.pop().end); } return true; }