diff --git a/NgxHTML.sublime-syntax b/NgxHTML.sublime-syntax index 9e401b3..f1fea55 100644 --- a/NgxHTML.sublime-syntax +++ b/NgxHTML.sublime-syntax @@ -10,24 +10,6 @@ file_extensions: - ngx - component.html -variables: - - bin_digit: '[01_]' - oct_digit: '[0-7_]' - dec_digit: '[0-9_]' - hex_digit: '[\h_]' - dec_integer: (?:0|[1-9]{{dec_digit}}*) - dec_exponent: '[Ee](?:[-+]|(?![-+])){{dec_digit}}*' - - # JavaScript identifier - ident_name: (?:{{ident_start}}{{ident_part}}*{{ident_break}}) - ident_break: (?!{{ident_part}}) - ident_escape: (?:\\u(?:\h{4}|\{\h+\})) - ident_start: (?:[_$\p{L}\p{Nl}]|{{ident_escape}}) - ident_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{ident_escape}}) - - dot_accessor: (?:\??\.(?!\.)) - contexts: ###[ HTML CUSTOMIZATIONS ]##################################################### @@ -40,81 +22,93 @@ contexts: tag-attributes: - meta_prepend: true - - include: tag-ng-template-attribute - - include: tag-ng-reference-attribute - - include: tag-ng-bind-attribute - - include: tag-ng-on-attribute - - include: tag-ng-bindon-attribute + - include: ng-directives -###[ ANGULAR EXPRESSIONS ]##################################################### +###[ ANGULAR DIRECTIVES ]###################################################### - ng-expressions: - # https://angular.dev/guide/templates/expression-syntax - - include: ng-arrays - - include: ng-groups - - include: ng-objects - - include: ng-function-calls - - include: ng-filters - - include: ng-operators - - include: ng-constants - - include: ng-numbers - - include: ng-strings - - include: ng-variables - -###[ ANGULAR TAG ATTRIBUTES ]################################################## - - tag-ng-template-attribute: - - match: (\*)([a-zA-Z]\w*) - scope: meta.attribute-with-value.template.html + ng-directives: + # template + - match: (\*)(?:(ngIf)|(ngFor)|(ngSwitch(?:Case|Default))|([a-zA-Z]\w*)) + scope: meta.directive.template.ngx captures: - 1: punctuation.definition.template.html - 2: entity.other.attribute-name.template.html - push: - - tag-event-attribute-meta - - tag-event-attribute-assignment - - tag-ng-reference-attribute: + 1: punctuation.definition.template.ngx + 2: keyword.control.conditional.if.ngx + 3: keyword.control.loop.for.ngx + 4: keyword.control.conditional.case.ngx + 5: entity.other.attribute-name.template.ngx + push: ng-directive-assignment + # reference - match: (\#)([a-zA-Z]\w*) - scope: meta.attribute.reference.html + scope: meta.directive.reference.ngx captures: - 1: punctuation.definition.reference.html - 2: entity.other.attribute-name.reference.html - push: - - tag-event-attribute-meta - - tag-event-attribute-assignment - - tag-ng-bind-attribute: - - match: (\[)([a-zA-Z@][!\w.-]*)(\]) - scope: meta.attribute-with-value.bind.html + 1: punctuation.definition.reference.ngx + 2: entity.other.attribute-name.reference.ngx + push: ng-directive-assignment + # bind + - match: (\[)(?:(ngSwitch)|([a-zA-Z@][!\w.-]*))(\]) + scope: meta.directive.bind.ngx captures: - 1: punctuation.section.bind.begin.html - 2: entity.other.attribute-name.bind.html - 3: punctuation.section.bind.end.html - push: - - tag-event-attribute-meta - - tag-event-attribute-assignment - - tag-ng-on-attribute: + 1: punctuation.definition.bind.begin.ngx + 2: keyword.control.conditional.switch.ngx + 3: entity.other.attribute-name.bind.ngx + 4: punctuation.definition.bind.end.ngx + push: ng-directive-assignment + # on - match: (\()([a-zA-Z@][\w:.]*)(\)) - scope: meta.attribute-with-value.on.html + scope: meta.directive.on.ngx captures: - 1: punctuation.section.on.begin.html - 2: entity.other.attribute-name.on.html - 3: punctuation.section.on.end.html - push: - - tag-event-attribute-meta - - tag-event-attribute-assignment - - tag-ng-bindon-attribute: + 1: punctuation.definition.on.begin.ngx + 2: entity.other.attribute-name.on.ngx + 3: punctuation.definition.on.end.ngx + push: ng-directive-assignment + # bindon - match: (\[\()([a-zA-Z][\w.]*)(\)\]) - scope: meta.attribute-with-value.bindon.html + scope: meta.directive.bindon.ngx captures: - 1: punctuation.section.bindon.begin.html - 2: entity.other.attribute-name.bindon.html - 3: punctuation.section.bindon.end.html - push: - - tag-event-attribute-meta - - tag-event-attribute-assignment + 1: punctuation.definition.bindon.begin.ngx + 2: entity.other.attribute-name.bindon.ngx + 3: punctuation.definition.bindon.end.ngx + push: ng-directive-assignment + + ng-directive-assignment: + - meta_include_prototype: false + - meta_content_scope: meta.directive.ngx + - match: = + scope: meta.directive.ngx punctuation.separator.key-value.ngx + set: + - immediately-pop # workaround https://github.com/sublimehq/sublime_text/issues/4069 + - ng-directive-value + - include: else-pop + + ng-directive-value: + - meta_content_scope: meta.directive.value.ngx + - match: \" + scope: meta.string.ngx string.quoted.double.ngx punctuation.definition.string.begin.ngx + embed: ng-directive-expressions + embed_scope: meta.directive.value.ngx meta.string.ngx meta.embedded.expression.ngx source.ngx.embedded.html + escape: \" + escape_captures: + 0: meta.string.ngx string.quoted.double.ngx punctuation.definition.string.end.ngx + pop: 1 + - match: \' + scope: meta.string.ngx string.quoted.single.ngx punctuation.definition.string.begin.ngx + embed: ng-directive-expressions + embed_scope: meta.directive.value.ngx meta.string.ngx meta.embedded.expression.ngx source.ngx.embedded.html + escape: \' + escape_captures: + 0: meta.string.ngx string.quoted.single.ngx punctuation.definition.string.end.ngx + pop: 1 + - include: else-pop + + ng-directive-expressions: + - match: (trackBy)\s*(:) + captures: + 1: keyword.control.flow.ngx + 2: punctuation.separator.key-value.ngx + - include: ng-conditional-keywords + - include: ng-defer-keywords + - include: ng-for-keywords + - include: ng-expressions ###[ ANGULAR DECLARATIONS ]#################################################### @@ -240,9 +234,12 @@ contexts: - match: \) scope: punctuation.section.group.end.ngx pop: 1 + - include: ng-conditional-keywords + - include: ng-expressions + + ng-conditional-keywords: - match: as{{ident_break}} scope: keyword.operator.assignment.as.ngx - - include: ng-expressions ng-defer-group: - meta_include_prototype: false @@ -256,15 +253,22 @@ contexts: - match: \) scope: punctuation.section.group.end.ngx pop: 1 - - match: (?:idle|viewport|interaction|hover|immediatetimer){{ident_break}} - scope: constant.language.event.ngx + - include: ng-defer-keywords + - include: ng-expressions + + ng-defer-keywords: - match: (?:prefetch on|on|prefetch when|when){{ident_break}} scope: keyword.control.flow.ngx + push: ng-defer-event - match: (minimum|after)(\?) captures: 1: keyword.operator.word.ngx 2: keyword.control.question.ngx - - include: ng-expressions + + ng-defer-event: + - match: (?:idle|viewport|interaction|hover|immediatetimer){{ident_break}} + scope: constant.language.event.ngx + - include: else-pop ng-for-group: - meta_include_prototype: false @@ -278,30 +282,48 @@ contexts: - match: \) scope: punctuation.section.group.end.ngx pop: 1 + - include: ng-for-keywords + - include: ng-expressions + + ng-for-keywords: - match: track{{ident_break}} scope: keyword.control.flow.ngx - match: let{{ident_break}} scope: keyword.declation.variable.ngx - match: of{{ident_break}} scope: keyword.operator.iteration.ngx - - include: ng-expressions ###[ ANGULAR INTERPOLATIONS ]################################################## ng-interpolations: - match: '{{' - scope: meta.embedded.ngx.html punctuation.section.embedded.begin.ngx.html + scope: meta.embedded.expression.ngx.html punctuation.section.embedded.begin.ngx.html push: ng-interpolation-body ng-interpolation-body: - meta_include_prototype: false - - meta_content_scope: meta.embedded.ngx.html source.ngx.embedded.html + - meta_content_scope: meta.embedded.expression.ngx.html source.ngx.embedded.html - match: '}}' - scope: meta.embedded.ngx.html punctuation.section.embedded.end.ngx.html + scope: meta.embedded.expression.ngx.html punctuation.section.embedded.end.ngx.html pop: 1 - include: ng-expressions -###[ ANGULAR ARRAYS ]########################################################### +###[ ANGULAR EXPRESSIONS ]##################################################### + + ng-expressions: + # https://angular.dev/guide/templates/expression-syntax + - include: ng-arrays + - include: ng-groups + - include: ng-objects + - include: ng-function-calls + - include: ng-filters + - include: ng-operators + - include: ng-constants + - include: ng-numbers + - include: ng-strings + - include: ng-variables + +###[ ANGULAR ARRAYS ]########################################################## ng-arrays: - match: \[ @@ -646,3 +668,23 @@ contexts: ng-block-pop: - match: (?=[;)}]) pop: 1 + +############################################################################### + +variables: + + bin_digit: '[01_]' + oct_digit: '[0-7_]' + dec_digit: '[0-9_]' + hex_digit: '[\h_]' + dec_integer: (?:0|[1-9]{{dec_digit}}*) + dec_exponent: '[Ee](?:[-+]|(?![-+])){{dec_digit}}*' + + # JavaScript identifier + ident_name: (?:{{ident_start}}{{ident_part}}*{{ident_break}}) + ident_break: (?!{{ident_part}}) + ident_escape: (?:\\u(?:\h{4}|\{\h+\})) + ident_start: (?:[_$\p{L}\p{Nl}]|{{ident_escape}}) + ident_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{ident_escape}}) + + dot_accessor: (?:\??\.(?!\.)) diff --git a/messages/recent.txt b/messages/recent.txt new file mode 100644 index 0000000..c9fec05 --- /dev/null +++ b/messages/recent.txt @@ -0,0 +1,5 @@ +# Ngx HTML Syntax 1.0+ + +Huge thanks to @deathaxe for rewriting the whole syntax to properly incorporate Angular Expressions. + +Now we have highly accurate syntax highlighting in component html files. diff --git a/tests/syntax_test_scopes.component.html b/tests/syntax_test_scopes.component.html index d5fbd8e..ef3ebe1 100644 --- a/tests/syntax_test_scopes.component.html +++ b/tests/syntax_test_scopes.component.html @@ -160,9 +160,9 @@ {{ a }} is greater than {{ b }} - - - + + + @@ -184,9 +184,9 @@ {{ a() }} is less than {{ b.c() }} - - - + + + @@ -206,9 +206,9 @@ {{ a }} is equal to {{ b }} - - - + + + @@ -235,7 +235,7 @@ {{ startDate }} - + @@ -357,12 +357,12 @@ Item #{{ idx }}: {{ item.name }} - + - + @@ -390,7 +390,7 @@ - + @@ -489,7 +489,7 @@ {{ "\xAF \u2AFF \n \"" }} - + @@ -534,7 +534,7 @@ {{ { name: 'Alice', 'object': { array + "name": [0, 2, 3] } } }} - + @@ -607,7 +607,7 @@ {{ foo ? bar : baz }} - + @@ -618,7 +618,7 @@ {{ foo = null ?? 'default' }} - + @@ -631,7 +631,7 @@ {{ person['name'][0] = "Mirabel" }} - + @@ -650,20 +650,20 @@ {{ obj?.member }} - - - - + + + + {{ obj.member [5] }} - - - - + + + + @@ -672,10 +672,10 @@ {{ obj.method() }} - - - - + + + + @@ -685,10 +685,10 @@ {{ orders.value()?.[0]?.$extra?.#currency }} - - - - + + + + @@ -709,7 +709,7 @@ {{ func(arg, "value") }} - + @@ -723,7 +723,7 @@ {{ var | filter | annimation ("forward") }} - + @@ -740,3 +740,282 @@ + + + + +