From f2e1251009a5dd5db61c28f02696aedf33338a29 Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 10 Feb 2026 00:45:38 +0100 Subject: fix: Use placeholder technique to prevent syntax highlighting overlap Replace comments/strings with placeholders, highlight rest, restore. Co-Authored-By: Claude Sonnet 4.5 --- tools/shader_editor/index.html | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'tools/shader_editor/index.html') diff --git a/tools/shader_editor/index.html b/tools/shader_editor/index.html index c7feffc..bad0abb 100644 --- a/tools/shader_editor/index.html +++ b/tools/shader_editor/index.html @@ -682,36 +682,44 @@ const syntaxHighlight = document.getElementById('syntax-highlight'); let composeTimeout = null; function highlightWGSL(code) { - let highlighted = code + const escaped = code .replace(/&/g, '&') .replace(//g, '>'); - // Tokenize to avoid overlapping matches - const tokens = []; - let lastIndex = 0; + // Use placeholders to prevent overlapping matches + const placeholders = []; + let result = escaped; - // Match comments, strings, then keywords/types/etc + // Process in priority order: comments, strings, then syntax const patterns = [ { regex: /\/\/.*$/gm, className: 'hl-comment' }, { regex: /"(?:[^"\\]|\\.)*"/g, className: 'hl-string' }, - { regex: /@\w+/g, className: 'hl-attribute' }, - { regex: /\b(?:fn|var|let|const|struct|if|else|for|while|return|break|continue|switch|case|default|loop|continuing)\b/g, className: 'hl-keyword' }, - { regex: /\b(?:f32|i32|u32|bool|vec2|vec3|vec4|mat2x2|mat3x3|mat4x4|sampler|texture_2d|array)\b/g, className: 'hl-type' }, - { regex: /\b\d+\.?\d*\b/g, className: 'hl-number' }, - { regex: /\b[a-z_]\w*(?=\s*\()/g, className: 'hl-function' }, ]; - // Simple sequential replacement (good enough for basic highlighting) + // Replace comments and strings with placeholders first patterns.forEach(({ regex, className }) => { - highlighted = highlighted.replace(regex, match => { - // Don't re-highlight if already inside a span - if (/${match}`; + result = result.replace(regex, match => { + const placeholder = `__PLACEHOLDER_${placeholders.length}__`; + placeholders.push(`${match}`); + return placeholder; }); }); - return highlighted; + // Now highlight syntax in remaining text + result = result + .replace(/@\w+/g, '$&') + .replace(/\b(?:fn|var|let|const|struct|if|else|for|while|return|break|continue|switch|case|default|loop|continuing)\b/g, '$&') + .replace(/\b(?:f32|i32|u32|bool|vec2|vec3|vec4|mat2x2|mat3x3|mat4x4|sampler|texture_2d|array)\b/g, '$&') + .replace(/\b\d+\.?\d*\b/g, '$&') + .replace(/\b[a-z_]\w*(?=\s*\()/g, '$&'); + + // Restore placeholders + placeholders.forEach((replacement, i) => { + result = result.replace(`__PLACEHOLDER_${i}__`, replacement); + }); + + return result; } function updateHighlight() { -- cgit v1.2.3