From 6c14550cc820607583df4a7dd6d1e3e1d6350860 Mon Sep 17 00:00:00 2001 From: Jeremy Bolding Date: Mon, 18 Dec 2023 20:17:18 -0600 Subject: [PATCH 1/3] [Added] Angular v17 Control-Block Syntax (#24) * Update NgxHTML.sublime-syntax * Update NgxHTML.sublime-syntax --- NgxHTML.sublime-syntax | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/NgxHTML.sublime-syntax b/NgxHTML.sublime-syntax index f9937b3..023fdc9 100644 --- a/NgxHTML.sublime-syntax +++ b/NgxHTML.sublime-syntax @@ -8,10 +8,14 @@ version: 2 extends: Packages/HTML/HTML.sublime-syntax +variables: + angular_blocks: (?<=\@)\b(?xi:for | if | else | else if | switch | case | empty | placeholder | defer | default | error | loading)\b + contexts: main: - meta_prepend: true - include: interpolation + - include: angular-blocks interpolation: - match: '{{' @@ -82,3 +86,33 @@ contexts: push: - tag-event-attribute-meta - tag-event-attribute-assignment + + + angular-blocks: + - match: '(@){{angular_blocks}}' + scope: keyword.control.control-flow.html + captures: + 1: punctuation.definition.keyword.html + - match: \( + scope: punctuation.section.group.begin.html + push: + - meta_scope: meta.group.html + - match: \b(async)\b + scope: keyword.control.html + - match: \b(track|of|prefetch on|on|prefetch when|when|as)\b + scope: keyword.operator.word.html + - match: \b(minimum|after)\b(\?) + captures: + 1: keyword.operator.word.html + 2: keyword.control.question.html + - match: \) + scope: punctuation.section.group.end.html + pop: 1 + - match: \{ + scope: punctuation.section.block.begin.html + push: + - meta_scope: meta.block.html + - include: main + - match: \} + scope: punctuation.section.block.end.html + pop: 1 From d4adb09e8b158047d7bbeb186eb324a46d2745e6 Mon Sep 17 00:00:00 2001 From: Po Chen Date: Tue, 16 Jan 2024 21:52:53 +1100 Subject: [PATCH 2/3] Add tests and fix leaking braces (#25) * add tests * add header * add more cases * do not leak braces into html context * test basics * bump action * fail it * add more --- .github/workflows/test.yaml | 16 +++ NgxHTML.sublime-syntax | 45 +++--- tests/syntax_test_control_flow.component.html | 136 ++++++++++++++++++ 3 files changed, 175 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/test.yaml create mode 100644 tests/syntax_test_control_flow.component.html diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..2bde098 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,16 @@ +name: Syntax Tests + +on: [push, pull_request] + +jobs: + st4_syntax_tests: + name: Run ST4 Syntax Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: SublimeText/syntax-test-action@v2 + with: + build: 4152 + default_packages: v4152 + package_name: Ngx HTML diff --git a/NgxHTML.sublime-syntax b/NgxHTML.sublime-syntax index 023fdc9..49a9ca8 100644 --- a/NgxHTML.sublime-syntax +++ b/NgxHTML.sublime-syntax @@ -93,26 +93,27 @@ contexts: scope: keyword.control.control-flow.html captures: 1: punctuation.definition.keyword.html - - match: \( - scope: punctuation.section.group.begin.html push: - - meta_scope: meta.group.html - - match: \b(async)\b - scope: keyword.control.html - - match: \b(track|of|prefetch on|on|prefetch when|when|as)\b - scope: keyword.operator.word.html - - match: \b(minimum|after)\b(\?) - captures: - 1: keyword.operator.word.html - 2: keyword.control.question.html - - match: \) - scope: punctuation.section.group.end.html - pop: 1 - - match: \{ - scope: punctuation.section.block.begin.html - push: - - meta_scope: meta.block.html - - include: main - - match: \} - scope: punctuation.section.block.end.html - pop: 1 + - match: \{ + scope: punctuation.section.block.begin.html + push: + - meta_scope: meta.block.html + - include: main + - match: \} + scope: punctuation.section.block.end.html + pop: 2 + - match: \( + scope: punctuation.section.group.begin.html + push: + - meta_scope: meta.group.html + - match: \b(async)\b + scope: keyword.control.html + - match: \b(track|of|prefetch on|on|prefetch when|when|as)\b + scope: keyword.operator.word.html + - match: \b(minimum|after)\b(\?) + captures: + 1: keyword.operator.word.html + 2: keyword.control.question.html + - match: \) + scope: punctuation.section.group.end.html + pop: 1 diff --git a/tests/syntax_test_control_flow.component.html b/tests/syntax_test_control_flow.component.html new file mode 100644 index 0000000..6aec2da --- /dev/null +++ b/tests/syntax_test_control_flow.component.html @@ -0,0 +1,136 @@ + + +@if (loggedIn) { + + + + + The user is logged in +} @else { + + + + + + + + The user is not logged in +} + + +@if (a > b) { + {{ a }} is greater than {{ b }} + + + + +} + +@if (a > b) { + {{ a }} is greater than {{ b }} +} @else if (b > a) { + {{ a }} is less than {{ b }} +} @else { + {{ a }} is equal to {{ b }} +} + +@switch (accessLevel) { + @case ('admin') { + + + + + + } + @case ('moderator') { + + } + @default { + + } +} + +@for (user of users; track user.id) { + {{ user.name }} +} @empty { + Empty list of users +} + +@defer { + +} + +@defer (on viewport) { + +} @placeholder { + + +} + +@defer (on viewport) { + +} @loading { + Loading… +} @error { + Loading failed :( +} @placeholder { + +} + +@defer (on viewport; prefetch on idle) { + +} + +@for (item of items; track item.id; let idx = $index, e = $even) { + Item #{{ idx }}: {{ item.name }} +} + +@for (item of items) { + {{ item.title }} +} + +@for (item of items) { + {{ item.title }} +} @empty { +

No Items

+} + +@for (item of items; track item.name) { +
  • {{ item.name }}
  • +} @empty { +
  • There are no items.
  • +} + +@if (users$ | async; as users) { + {{ users.length }} +} + +@for (item of items; track item.id) { + {{ item.name }} +} + +@switch (condition) { + @case (caseA) { + Case A. + } + @case (caseB) { + Case B. + } + @default { + Default case. + } +} + +@defer (on ; when ; prefetch on ; prefetch when ) { + + +} @placeholder (minimum? ) { + +

    Placeholder

    +} @loading (minimum? ; after? ) { + + loading image +} @error { + +

    An loading error occured

    +} From 5ab46f79d9e6472b1637a0ca34ec50d0b09049f8 Mon Sep 17 00:00:00 2001 From: Po Chen Date: Tue, 16 Jan 2024 22:00:12 +1100 Subject: [PATCH 3/3] update readme --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index 55469b6..54ab69c 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,48 @@ Highlighting the JS part as JS. So, - in `a && b` within an Angular expression, you should see `&&` correctly highlighted as the JS operator instead of an error you would see in normal HTML syntax. - in `{{1 + 2}}` interpolations, you should see JS syntax highlighting as well +## And... + +Now it supports Angular control flow. + +``` +@for (item of items) { + {{item.title}} +} @empty { +

    No Items

    +} +``` + +``` +@if (users$ | async; as users) { + {{ users.length }} +} +``` + +``` +@if (a > b) { + {{a}} is greater than {{b}} +} @else if (b > a) { + {{a}} is less than {{b}} +} @else { + {{a}} is equal to {{b}} +} +``` + +``` +@switch (condition) { + @case (caseA) { + Case A. + } + @case (caseB) { + Case B. + } + @default { + Default case. + } +} +``` + ## How to use The syntax is listed as `Ngx HTML` in Sublime syntax selection list.