window.playground.highlightConcreteSyntaxMatches = function()

in playground/tree-sitter/concrete-syntax.js [573:687]


    window.playground.highlightConcreteSyntaxMatches = function(matches) {
        debugLog('highlightConcreteSyntaxMatches function called with:', matches);
        // Clear existing highlights first
        const codeEditor = window.playground.codeEditor;
        if (!codeEditor) return;

        // Clear previous concrete syntax highlights
        codeEditor.getAllMarks().forEach(mark => {
            if (mark.className && mark.className.startsWith('concrete-syntax')) {
                mark.clear();
            }
        });

        if (!matches || matches.length === 0) return;

        // Use playground's color scheme for consistency
        const colors = window.playground.LIGHT_COLORS || [
            "#0550ae", "#ab5000", "#116329", "#844708", "#6639ba", 
            "#7d4e00", "#0969da", "#1a7f37", "#cf222e", "#8250df"
        ];

        debugLog('Highlighting matches:', matches);
        
        matches.forEach((match, index) => {
            debugLog('Match', index, ':', match);
            // Handle both snake_case and camelCase field names
            const range = match.range;
            const startPoint = range.startPoint || range.start_point;
            const endPoint = range.endPoint || range.end_point;
            
            if (range && startPoint && endPoint) {
                const from = {
                    line: startPoint.row,
                    ch: startPoint.column
                };
                const to = {
                    line: endPoint.row, 
                    ch: endPoint.column
                };

                // Highlight the full match with primary color
                codeEditor.markText(from, to, {
                    css: `background-color: ${colors[0]}20; border: 1px solid ${colors[0]}60;`,
                    title: `Concrete Syntax Match ${index + 1}`
                });

                // Highlight captured variables with different colors
                const captures = match.matches;
                if (captures && typeof captures === 'object') {
                    let colorIndex = 1;
                    debugLog('Match captures:', captures);
                    
                    // Handle both Map and plain object
                    const captureEntries = captures instanceof Map ? 
                        Array.from(captures.entries()) : 
                        Object.entries(captures);
                    
                    captureEntries.forEach(([key, captureData]) => {
                        debugLog('Capture:', key, captureData);
                        if (key !== '*' && captureData) {
                            const captureColor = colors[colorIndex % colors.length];
                            
                            // Check if captureData has range information (CapturedNode structure)
                            const captureRange = captureData.range;
                            const captureStartPoint = captureRange?.startPoint || captureRange?.start_point;
                            const captureEndPoint = captureRange?.endPoint || captureRange?.end_point;
                            
                            if (captureRange && captureStartPoint && captureEndPoint) {
                                // Use exact range from capture data
                                const captureFrom = {
                                    line: captureStartPoint.row,
                                    ch: captureStartPoint.column
                                };
                                const captureTo = {
                                    line: captureEndPoint.row,
                                    ch: captureEndPoint.column
                                };
                                
                                debugLog(`Highlighting capture ${key} from (${captureFrom.line},${captureFrom.ch}) to (${captureTo.line},${captureTo.ch})`);
                                
                                codeEditor.markText(captureFrom, captureTo, {
                                    css: `background-color: ${captureColor}30; border: 1px solid ${captureColor}; border-radius: 2px;`,
                                    title: `${key}: ${captureData.text || captureData}`
                                });
                            } else if (typeof captureData === 'string') {
                                // Fallback: find the capture text within the match
                                const matchText = match.matchedString || match.matched_string || '';
                                const captureStart = matchText.indexOf(captureData);
                                
                                if (captureStart >= 0) {
                                    const captureFrom = {
                                        line: from.line,
                                        ch: from.ch + captureStart
                                    };
                                    const captureTo = {
                                        line: from.line, 
                                        ch: from.ch + captureStart + captureData.length
                                    };
                                    
                                    debugLog(`Highlighting string capture ${key} from (${captureFrom.line},${captureFrom.ch}) to (${captureTo.line},${captureTo.ch})`);
                                    
                                    codeEditor.markText(captureFrom, captureTo, {
                                        css: `background-color: ${captureColor}30; border: 1px solid ${captureColor}; border-radius: 2px;`,
                                        title: `${key}: ${captureData}`
                                    });
                                }
                            }
                            
                            colorIndex++;
                        }
                    });
                }
            }
        });
    };