Skip to content

Add parsing for end of comment when using whitespace control + add tooling for testing#113

Merged
daaain merged 3 commits into
masterfrom
fix-comment-closing-plus-tooling
Jun 29, 2026
Merged

Add parsing for end of comment when using whitespace control + add tooling for testing#113
daaain merged 3 commits into
masterfrom
fix-comment-closing-plus-tooling

Conversation

@daaain

@daaain daaain commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Fixes #112

Summary by CodeRabbit

  • New Features
    • Improved Handlebars syntax highlighting for whitespace-control tildes (~) in inline/block comments and block tags.
    • Tightened YAML front-matter --- delimiter detection and refined embedded Handlebars highlighting in surrounding HTML/script contexts.
  • Tests
    • Added Node.js test suites for expressions, blocks, comments, and embedded scenarios, plus shared grammar/tokenization helpers.
  • Chores
    • Added CI test workflow and a test script; updated .gitignore to exclude node_modules/.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd8b2e3d-2eda-4599-a3c8-f945d953771a

📥 Commits

Reviewing files that changed from the base of the PR and between ce8d815 and 316c656.

📒 Files selected for processing (1)
  • test/helpers/grammar.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/helpers/grammar.js

📝 Walkthrough

Walkthrough

Updates Handlebars grammar patterns for tilde-aware comment delimiters and anchored YAML front-matter delimiters across all supported grammar formats. Adds a Node-based tokenization test harness, CI workflow, and test coverage for comments, expressions, blocks, and embedding.

Changes

Handlebars Grammar Fix and Test Suite

Layer / File(s) Summary
Comment regex tilde support
grammars/Handlebars.json, grammars/Handlebars.tmLanguage, grammars/Handlebars.sublime-syntax
Block and inline comment delimiter regexes now accept optional ~ markers around opening and closing delimiters in all three grammar formats.
YAML front-matter delimiter matching
grammars/Handlebars.json, grammars/Handlebars.tmLanguage, grammars/Handlebars.sublime-syntax
YAML front-matter start and end delimiter regexes were updated to use anchored --- matching.
Test helper and project setup
test/helpers/grammar.js, package.json, .github/workflows/test.yml, .gitignore
Adds the shared grammar-loading helper, Node test script and dependencies, CI workflow, and node_modules/ ignore entry.
Comment scope tests
test/comments.test.js
Adds comment scope tests for block and inline comment forms with whitespace-control tildes and line-level scope boundaries.
Expression and block scope tests
test/expressions.test.js, test/blocks.test.js
Adds scope tests for expressions and block tags, including helpers, arguments, block parameters, else sections, and whitespace-control delimiters.
Embedding scope tests
test/embedding.test.js
Adds embedding tests for Handlebars in HTML attributes, layout preprocessor syntax, inline script templates, plain HTML exclusion, and YAML front-matter handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 A tilde hopped in with a tiny grin,
and comments no longer keep lines within.
Blocks, embeds, and front-matter shine,
helper paws tapped the token line.
Now every scope can hop neat and bright,
with tests to keep the grammar right.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also changes YAML front-matter parsing and adds broad grammar tests/tooling beyond the comment-whitespace bug in #112. Move the YAML front-matter and other unrelated grammar/test expansions into a separate PR unless they are required for the comment fix.
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly describes the main change: comment parsing for whitespace control plus testing tooling.
Linked Issues check ✅ Passed The grammar updates and regression tests directly address #112 by recognizing --~}} comments and stopping comment scope spillover.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-comment-closing-plus-tooling

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test.yml:
- Around line 16-23: The test workflow currently uses actions/checkout@v4 with
default credential persistence, which leaves write-capable git credentials
available to PR-controlled steps. Update the checkout step to disable persisted
credentials, and adjust the job permissions so it only has read-only contents
access. Keep the change localized to the workflow job that runs npm ci and npm
test.

In `@test/blocks.test.js`:
- Around line 68-74: The whitespace-control block assertions in blocks.test.js
are using the wrong token text for the opening delimiter. Update the relevant
assertScope calls in the whitespace-control block test to look up the exact
`{{~` token text, matching the behavior already used in the expression
whitespace-control suite, so `scopesOf()` can find the token consistently for
both the block start and end cases.

In `@test/embedding.test.js`:
- Around line 44-51: The scope assertion in tokenizeLines() is too broad because
lines.flat() includes tokens from the <script> opener and </script> closer, not
just the embedded template body. Update the test around tokenizeLines(src) to
only iterate over the script body tokens, using the existing src fixture and the
relevant token/scoping checks in test/embedding.test.js, so the
source.handlebars.embedded.html assertion applies only to the embedded content.

In `@test/helpers/grammar.js`:
- Around line 26-33: Update the grammar loader in `test/helpers/grammar.js` so
`loadGrammar` can serve every external scope referenced by
`grammars/Handlebars.json`, not just `SCOPE_NAME`. Extend the `vsctm.Registry`
setup to map and return parsed grammars for `text.html.handlebars`,
`text.html.basic`, `source.css`, and `source.js`, using the existing
`vsctm.parseRawGrammar`/`fs.readFileSync` flow so the tokenizer harness resolves
embedded HTML, CSS, and JS paths correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d52aa1e-87b1-4875-ae04-a7bda0dbedd6

📥 Commits

Reviewing files that changed from the base of the PR and between 9fb01fe and b254c59.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • .github/workflows/test.yml
  • .gitignore
  • grammars/Handlebars.json
  • grammars/Handlebars.sublime-syntax
  • grammars/Handlebars.tmLanguage
  • package.json
  • test/blocks.test.js
  • test/comments.test.js
  • test/embedding.test.js
  • test/expressions.test.js
  • test/helpers/grammar.js

Comment thread .github/workflows/test.yml
Comment thread test/blocks.test.js
Comment on lines +68 to +74
test('whitespace control on a block: {{~#if x~}} ... {{~/if~}}', async () => {
await assertScope('{{~#if x~}}', '{{', 'meta.function.block.start.handlebars');
await assertScope('{{~#if x~}}', '~#', 'keyword.control');
await assertScope('{{~#if x~}}', '~}}', 'support.constant.handlebars');
await assertScope('{{~/if~}}', '{{', 'meta.function.block.end.handlebars');
await assertScope('{{~/if~}}', '~/', 'keyword.control');
await assertScope('{{~/if~}}', '~}}', 'support.constant.handlebars');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the exact {{~ token text in the whitespace-control block assertions.

scopesOf() does an exact t.text lookup, and the sibling expression suite already treats the whitespace-control prefix as {{~ (test/expressions.test.js:70). With the current {{ lookup here, these assertions will throw no token with text "{{" as soon as block delimiters are tokenized the same way.

Suggested fix
 test('whitespace control on a block: {{~`#if` x~}} ... {{~/if~}}', async () => {
-  await assertScope('{{~`#if` x~}}', '{{', 'meta.function.block.start.handlebars');
+  await assertScope('{{~`#if` x~}}', '{{~', 'meta.function.block.start.handlebars');
   await assertScope('{{~`#if` x~}}', '~#', 'keyword.control');
   await assertScope('{{~`#if` x~}}', '~}}', 'support.constant.handlebars');
-  await assertScope('{{~/if~}}', '{{', 'meta.function.block.end.handlebars');
+  await assertScope('{{~/if~}}', '{{~', 'meta.function.block.end.handlebars');
   await assertScope('{{~/if~}}', '~/', 'keyword.control');
   await assertScope('{{~/if~}}', '~}}', 'support.constant.handlebars');
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test('whitespace control on a block: {{~#if x~}} ... {{~/if~}}', async () => {
await assertScope('{{~#if x~}}', '{{', 'meta.function.block.start.handlebars');
await assertScope('{{~#if x~}}', '~#', 'keyword.control');
await assertScope('{{~#if x~}}', '~}}', 'support.constant.handlebars');
await assertScope('{{~/if~}}', '{{', 'meta.function.block.end.handlebars');
await assertScope('{{~/if~}}', '~/', 'keyword.control');
await assertScope('{{~/if~}}', '~}}', 'support.constant.handlebars');
test('whitespace control on a block: {{~`#if` x~}} ... {{~/if~}}', async () => {
await assertScope('{{~`#if` x~}}', '{{~', 'meta.function.block.start.handlebars');
await assertScope('{{~`#if` x~}}', '~#', 'keyword.control');
await assertScope('{{~`#if` x~}}', '~}}', 'support.constant.handlebars');
await assertScope('{{~/if~}}', '{{~', 'meta.function.block.end.handlebars');
await assertScope('{{~/if~}}', '~/', 'keyword.control');
await assertScope('{{~/if~}}', '~}}', 'support.constant.handlebars');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/blocks.test.js` around lines 68 - 74, The whitespace-control block
assertions in blocks.test.js are using the wrong token text for the opening
delimiter. Update the relevant assertScope calls in the whitespace-control block
test to look up the exact `{{~` token text, matching the behavior already used
in the expression whitespace-control suite, so `scopesOf()` can find the token
consistently for both the block start and end cases.

Comment thread test/embedding.test.js
Comment thread test/helpers/grammar.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/helpers/grammar.js`:
- Around line 28-43: The catch-all fallback in loadGrammar is masking unexpected
scope references and can hide broken grammar changes. Update the
loadGrammar(scopeName) logic in test/helpers/grammar.js to return the empty stub
only for the known built-in scopes used by the grammar (text.html.basic,
source.css, source.js, source.yaml), and fail fast by throwing for any other
unknown scope so typos and newly introduced missing includes are caught by the
test harness.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 974927ee-eecc-47cf-9a45-cc4c1b8fa158

📥 Commits

Reviewing files that changed from the base of the PR and between b254c59 and ce8d815.

📒 Files selected for processing (6)
  • .github/workflows/test.yml
  • grammars/Handlebars.json
  • grammars/Handlebars.sublime-syntax
  • grammars/Handlebars.tmLanguage
  • test/embedding.test.js
  • test/helpers/grammar.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/test.yml

Comment thread test/helpers/grammar.js Outdated
@daaain daaain merged commit adc200e into master Jun 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handlebars syntax highlighter does not recognize end of comment when using whitespace control (~) before closing braces

1 participant