Simplify grammar patterns for tree-sitter compatibility
- Use simple regex patterns for comments, raw blocks, embedded languages - Add support for unquoted import paths - Use string literals for keyword highlighting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7c37d0b3bc
commit
769d8bfc51
261
grammar.js
261
grammar.js
|
|
@ -40,9 +40,11 @@ module.exports = grammar({
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Template imports
|
// Template imports - supports both quoted "path" and unquoted /path
|
||||||
import_statement: ($) =>
|
import_statement: ($) =>
|
||||||
seq("@import", $.string_literal, "as", $.identifier),
|
seq("@import", choice($.string_literal, $.import_path), "as", $.identifier),
|
||||||
|
|
||||||
|
import_path: ($) => /\/[^\s]+/,
|
||||||
|
|
||||||
// Struct definition
|
// Struct definition
|
||||||
struct_definition: ($) =>
|
struct_definition: ($) =>
|
||||||
|
|
@ -100,7 +102,7 @@ module.exports = grammar({
|
||||||
|
|
||||||
// Function definition
|
// Function definition
|
||||||
function_definition: ($) =>
|
function_definition: ($) =>
|
||||||
seq("@func", $.identifier, $.parameter_list, $.content_block),
|
seq("@fn", $.identifier, $.parameter_list, $.content_block),
|
||||||
|
|
||||||
parameter_list: ($) =>
|
parameter_list: ($) =>
|
||||||
seq(
|
seq(
|
||||||
|
|
@ -128,6 +130,7 @@ module.exports = grammar({
|
||||||
$.template_control_flow,
|
$.template_control_flow,
|
||||||
$.template_expression,
|
$.template_expression,
|
||||||
$.comment,
|
$.comment,
|
||||||
|
$.raw_block,
|
||||||
$.embedded_language,
|
$.embedded_language,
|
||||||
$.escape_at,
|
$.escape_at,
|
||||||
$.text_content,
|
$.text_content,
|
||||||
|
|
@ -223,7 +226,7 @@ module.exports = grammar({
|
||||||
),
|
),
|
||||||
|
|
||||||
expression_path: ($) =>
|
expression_path: ($) =>
|
||||||
prec.left(seq(
|
seq(
|
||||||
$.identifier,
|
$.identifier,
|
||||||
repeat(
|
repeat(
|
||||||
choice(
|
choice(
|
||||||
|
|
@ -232,7 +235,7 @@ module.exports = grammar({
|
||||||
seq("(", optional($.argument_list), ")"),
|
seq("(", optional($.argument_list), ")"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)),
|
),
|
||||||
|
|
||||||
// Control flow
|
// Control flow
|
||||||
template_control_flow: ($) =>
|
template_control_flow: ($) =>
|
||||||
|
|
@ -564,259 +567,25 @@ module.exports = grammar({
|
||||||
// Comments
|
// Comments
|
||||||
comment: ($) => choice($.template_comment, $.html_comment),
|
comment: ($) => choice($.template_comment, $.html_comment),
|
||||||
|
|
||||||
// Template comments support variable asterisk counts: @* *@, @** **@, @*** ***@
|
// Template comments: @* ... *@ (simple form only for syntax highlighting)
|
||||||
template_comment: ($) =>
|
template_comment: ($) =>
|
||||||
choice($.template_comment_1, $.template_comment_2, $.template_comment_3),
|
seq("@", /\*+/, optional(/([^*]|\*+[^@])*/), /\*+/, "@"),
|
||||||
|
|
||||||
// Single asterisk: @* ... *@
|
|
||||||
template_comment_1: ($) =>
|
|
||||||
seq("@*", optional($.comment_content_1), "*@"),
|
|
||||||
comment_content_1: ($) => /([^*]|\*[^@])*/,
|
|
||||||
|
|
||||||
// Double asterisk: @** ... **@
|
|
||||||
template_comment_2: ($) =>
|
|
||||||
seq("@**", optional($.comment_content_2), "**@"),
|
|
||||||
comment_content_2: ($) => /([^*]|\*[^*]|\*\*[^@])*/,
|
|
||||||
|
|
||||||
// Triple asterisk: @*** ... ***@
|
|
||||||
template_comment_3: ($) =>
|
|
||||||
seq("@***", optional($.comment_content_3), "***@"),
|
|
||||||
comment_content_3: ($) => /([^*]|\*[^*]|\*\*[^*]|\*\*\*[^@])*/,
|
|
||||||
|
|
||||||
// HTML comment: <!-- ... -->
|
// HTML comment: <!-- ... -->
|
||||||
html_comment: ($) => seq("<!--", optional($.html_comment_content), "-->"),
|
html_comment: ($) => seq("<!--", optional($.html_comment_content), "-->"),
|
||||||
|
|
||||||
html_comment_content: ($) => /([^-]|-[^-]|--[^>])*/,
|
html_comment_content: ($) => /([^-]|-[^-]|--[^>])*/,
|
||||||
|
|
||||||
|
// Raw blocks: @#...#@ (simple form only for syntax highlighting)
|
||||||
|
raw_block: ($) =>
|
||||||
|
seq("@", /#+/, optional(/([^#]|#+[^@])*/), /#+/, "@"),
|
||||||
|
|
||||||
// Embedded language blocks: @```lang ... ```@
|
// Embedded language blocks: @```lang ... ```@
|
||||||
embedded_language: ($) =>
|
embedded_language: ($) =>
|
||||||
choice(
|
seq("@", /`+/, $.language_name, optional(/([^`]|`+[^@])*/), /`+/, "@"),
|
||||||
// JSON/Alpine blocks with structured parsing
|
|
||||||
seq("@```", choice("json", "alpine"), optional($.json_content), "```@"),
|
|
||||||
// JS blocks with structured parsing
|
|
||||||
seq("@```", choice("js", "javascript"), optional($.js_content), "```@"),
|
|
||||||
// CSS blocks with structured parsing
|
|
||||||
seq("@```", choice("css", "style"), optional($.css_content), "```@"),
|
|
||||||
// HTML blocks (less common, use simple content)
|
|
||||||
seq("@```", "html", optional($.embedded_content_simple), "```@"),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Simple embedded content fallback
|
|
||||||
embedded_content_simple: ($) => /([^`]|`[^`]|``[^`])*/,
|
|
||||||
|
|
||||||
language_name: ($) =>
|
language_name: ($) =>
|
||||||
choice("html", "css", "js", "javascript", "json", "alpine", "style"),
|
choice("html", "css", "js", "javascript", "json", "alpine", "style"),
|
||||||
|
|
||||||
// JSON content with template support
|
|
||||||
json_content: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_object,
|
|
||||||
$.json_array,
|
|
||||||
),
|
|
||||||
|
|
||||||
json_object: ($) =>
|
|
||||||
seq(
|
|
||||||
"{",
|
|
||||||
optional($.json_object_content),
|
|
||||||
"}",
|
|
||||||
),
|
|
||||||
|
|
||||||
json_object_content: ($) =>
|
|
||||||
seq(
|
|
||||||
$.json_member_or_control,
|
|
||||||
repeat(seq(optional(","), $.json_member_or_control)),
|
|
||||||
optional(","),
|
|
||||||
),
|
|
||||||
|
|
||||||
json_member_or_control: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_member,
|
|
||||||
$.json_control_flow,
|
|
||||||
),
|
|
||||||
|
|
||||||
json_member: ($) =>
|
|
||||||
seq(
|
|
||||||
choice($.json_key, $.template_expression),
|
|
||||||
":",
|
|
||||||
$.json_value,
|
|
||||||
),
|
|
||||||
|
|
||||||
json_key: ($) =>
|
|
||||||
choice(
|
|
||||||
$.string_literal,
|
|
||||||
$.identifier, // Allow unquoted keys for JS object shorthand
|
|
||||||
),
|
|
||||||
|
|
||||||
json_value: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_object,
|
|
||||||
$.json_array,
|
|
||||||
$.string_literal,
|
|
||||||
$.number_literal,
|
|
||||||
$.boolean_literal,
|
|
||||||
"null",
|
|
||||||
$.template_expression,
|
|
||||||
$.json_method, // For Alpine.js method shorthand
|
|
||||||
),
|
|
||||||
|
|
||||||
json_array: ($) =>
|
|
||||||
seq(
|
|
||||||
"[",
|
|
||||||
optional($.json_array_content),
|
|
||||||
"]",
|
|
||||||
),
|
|
||||||
|
|
||||||
json_array_content: ($) =>
|
|
||||||
seq(
|
|
||||||
$.json_array_element,
|
|
||||||
repeat(seq(optional(","), $.json_array_element)),
|
|
||||||
optional(","),
|
|
||||||
),
|
|
||||||
|
|
||||||
json_array_element: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_value,
|
|
||||||
$.json_control_flow,
|
|
||||||
),
|
|
||||||
|
|
||||||
// Control flow in JSON context
|
|
||||||
json_control_flow: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_if_statement,
|
|
||||||
$.json_for_loop,
|
|
||||||
),
|
|
||||||
|
|
||||||
json_if_statement: ($) =>
|
|
||||||
seq(
|
|
||||||
"@if",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.json_if_body),
|
|
||||||
"}",
|
|
||||||
optional(seq("else", "{", optional($.json_if_body), "}")),
|
|
||||||
),
|
|
||||||
|
|
||||||
// Body of @if in JSON can contain members or array elements
|
|
||||||
json_if_body: ($) =>
|
|
||||||
seq(
|
|
||||||
$.json_if_element,
|
|
||||||
repeat(seq(optional(","), $.json_if_element)),
|
|
||||||
optional(","),
|
|
||||||
),
|
|
||||||
|
|
||||||
json_if_element: ($) =>
|
|
||||||
choice(
|
|
||||||
$.json_member,
|
|
||||||
$.json_value,
|
|
||||||
$.json_control_flow,
|
|
||||||
),
|
|
||||||
|
|
||||||
json_for_loop: ($) =>
|
|
||||||
seq(
|
|
||||||
"@for",
|
|
||||||
$.simple_pattern,
|
|
||||||
"in",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.json_if_body),
|
|
||||||
"}",
|
|
||||||
),
|
|
||||||
|
|
||||||
// Alpine.js method shorthand: toggle() { this.open = !this.open; }
|
|
||||||
json_method: ($) =>
|
|
||||||
seq(
|
|
||||||
$.identifier,
|
|
||||||
"(",
|
|
||||||
optional($.json_method_params),
|
|
||||||
")",
|
|
||||||
"{",
|
|
||||||
optional($.js_content),
|
|
||||||
"}",
|
|
||||||
),
|
|
||||||
|
|
||||||
json_method_params: ($) =>
|
|
||||||
seq($.identifier, repeat(seq(",", $.identifier))),
|
|
||||||
|
|
||||||
// JavaScript content with template support
|
|
||||||
js_content: ($) => repeat1($.js_element),
|
|
||||||
|
|
||||||
js_element: ($) =>
|
|
||||||
choice(
|
|
||||||
$.js_control_flow,
|
|
||||||
$.template_expression,
|
|
||||||
$.js_code,
|
|
||||||
),
|
|
||||||
|
|
||||||
js_control_flow: ($) =>
|
|
||||||
choice(
|
|
||||||
$.js_if_statement,
|
|
||||||
$.js_for_loop,
|
|
||||||
),
|
|
||||||
|
|
||||||
js_if_statement: ($) =>
|
|
||||||
seq(
|
|
||||||
"@if",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.js_content),
|
|
||||||
"}",
|
|
||||||
optional(seq("else", "{", optional($.js_content), "}")),
|
|
||||||
),
|
|
||||||
|
|
||||||
js_for_loop: ($) =>
|
|
||||||
seq(
|
|
||||||
"@for",
|
|
||||||
$.simple_pattern,
|
|
||||||
"in",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.js_content),
|
|
||||||
"}",
|
|
||||||
),
|
|
||||||
|
|
||||||
// Raw JS code (anything that's not @expression or @control_flow)
|
|
||||||
js_code: ($) => token(prec(-1, /[^@`]+/)),
|
|
||||||
|
|
||||||
// CSS content with template support
|
|
||||||
css_content: ($) => repeat1($.css_element),
|
|
||||||
|
|
||||||
css_element: ($) =>
|
|
||||||
choice(
|
|
||||||
$.css_control_flow,
|
|
||||||
$.template_expression,
|
|
||||||
$.css_code,
|
|
||||||
),
|
|
||||||
|
|
||||||
css_control_flow: ($) =>
|
|
||||||
choice(
|
|
||||||
$.css_if_statement,
|
|
||||||
$.css_for_loop,
|
|
||||||
),
|
|
||||||
|
|
||||||
css_if_statement: ($) =>
|
|
||||||
seq(
|
|
||||||
"@if",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.css_content),
|
|
||||||
"}",
|
|
||||||
optional(seq("else", "{", optional($.css_content), "}")),
|
|
||||||
),
|
|
||||||
|
|
||||||
css_for_loop: ($) =>
|
|
||||||
seq(
|
|
||||||
"@for",
|
|
||||||
$.simple_pattern,
|
|
||||||
"in",
|
|
||||||
$.expression,
|
|
||||||
"{",
|
|
||||||
optional($.css_content),
|
|
||||||
"}",
|
|
||||||
),
|
|
||||||
|
|
||||||
// Raw CSS code
|
|
||||||
css_code: ($) => token(prec(-1, /[^@`]+/)),
|
|
||||||
|
|
||||||
// Escape sequence for literal @
|
// Escape sequence for literal @
|
||||||
escape_at: ($) => "@@",
|
escape_at: ($) => "@@",
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
; Waltzing Template Highlights
|
; Waltzing Template Highlights
|
||||||
|
|
||||||
; Comments (all template comment variants)
|
; Comments
|
||||||
(template_comment) @comment
|
|
||||||
(template_comment_1) @comment
|
|
||||||
(template_comment_2) @comment
|
|
||||||
(template_comment_3) @comment
|
|
||||||
(html_comment) @comment
|
(html_comment) @comment
|
||||||
|
|
||||||
|
; Raw blocks (verbatim content)
|
||||||
|
(raw_block) @string.special
|
||||||
|
|
||||||
|
; Template comments
|
||||||
|
(template_comment) @comment
|
||||||
|
|
||||||
; Keywords
|
; Keywords
|
||||||
"@use" @keyword
|
"@use" @keyword
|
||||||
"@import" @keyword
|
"@import" @keyword
|
||||||
"@struct" @keyword
|
"@struct" @keyword
|
||||||
"@enum" @keyword
|
"@enum" @keyword
|
||||||
"@func" @keyword
|
"@fn" @keyword
|
||||||
"@let" @keyword
|
"@let" @keyword
|
||||||
"@if" @keyword
|
"@if" @keyword
|
||||||
"@for" @keyword
|
"@for" @keyword
|
||||||
|
|
@ -97,14 +99,8 @@
|
||||||
(escape_sequence) @escape
|
(escape_sequence) @escape
|
||||||
(escape_at) @escape
|
(escape_at) @escape
|
||||||
|
|
||||||
; Embedded language names
|
; Embedded
|
||||||
"json" @label
|
(language_name) @label
|
||||||
"alpine" @label
|
|
||||||
"js" @label
|
|
||||||
"javascript" @label
|
|
||||||
"css" @label
|
|
||||||
"style" @label
|
|
||||||
"html" @label
|
|
||||||
|
|
||||||
; Variables (fallback)
|
; Variables (fallback)
|
||||||
(identifier) @variable
|
(identifier) @variable
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue