Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Edge Template FormatterNew to Visual Studio Code? Get it now.
Edge Template Formatter

Edge Template Formatter

FODUU

|
1 install
| (0) | Free
Syntax highlighting, formatting, and IntelliSense for AdonisJS Edge templates (.edge files)
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Edge.js Formatter

A VS Code extension for AdonisJS Edge templates (.edge files) — syntax highlighting, smart formatting, code folding, and language support out of the box.

VS Code License Version


Features at a Glance

Feature What it does
Syntax Highlighting Full TextMate grammar for Edge directives, expressions, and embedded HTML/CSS/JS
Smart Formatting Auto-indents nested @component, @slot, @if, @each, and more on save
Code Folding Fold @slot→@end, @if→@else→@end blocks and HTML elements
Multi-line Attribute Joining Collapses multi-line HTML attributes (like style="...") into single lines
Inline Directive Splitting Automatically moves @if, @end, @slot, etc. to their own lines on save
Auto-Close Snippets Type @if and get auto-completed block with @end — press Tab to navigate
Error Diagnostics Red squiggly errors when @if/@end are used inside HTML tags — suggests ternary instead
Broken HTML Tag Repair Automatically fixes </span + > split across lines back into </span> on format
Smart Ternary Conversion Auto-converts simple @if(x) Yes @else No @end to {{ x ? 'Yes' : 'No' }} on format
Auto-Indent on Type Automatically aligns @end/@endsection to match their opening directive
Comment Support Toggle {{-- --}} block comments with Ctrl+/
Bracket Matching Auto-closes {{ }}, {{{ }}}, {{-- --}}, and standard HTML pairs
HTML → Edge Comment Conversion Auto-converts <!-- --> to {{-- --}} on save so comments don't ship to the browser
Script/Style Formatting Re-indents <script> and <style> block contents
Status Bar Indicator Shows "Edge" in the status bar when editing .edge files

Installation

From VS Code Marketplace

  1. Open VS Code
  2. Go to Extensions (Ctrl+Shift+X)
  3. Search for "Edge.js Formatter"
  4. Click Install

From VSIX File

code --install-extension edge-template-formatter-0.3.0.vsix

Quick Start

  1. Open any .edge file — the extension activates automatically
  2. Format the file with Shift+Alt+F
  3. Enable Format on Save for hands-free formatting:
// .vscode/settings.json
{
  "[edge]": {
    "editor.defaultFormatter": "foduu.edge-template-formatter",
    "editor.formatOnSave": true
  }
}

Formatting

How It Works

The formatter reads your .edge file and applies proper indentation based on the nesting structure of Edge directives and HTML elements.

Before / After

Before (messy indentation):

@component('layouts/default')
@slot('body')
<div class="container">
@if(user)
<h1>{{ user.name }}</h1>
@each(post in user.posts)
<article>
<h2>{{ post.title }}</h2>
</article>
@end
@end
</div>
@end
@end

After (formatted on save):

@component('layouts/default')
  @slot('body')
    <div class="container">
      @if(user)
        <h1>{{ user.name }}</h1>
        @each(post in user.posts)
          <article>
            <h2>{{ post.title }}</h2>
          </article>
        @end
      @end
    </div>
  @end
@end

Multi-line Attribute Joining

The formatter automatically collapses multi-line HTML attributes into a single line:

Before:

<div class="device-grid" style="
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 20px;
">

After:

<div class="device-grid" style="display: grid; grid-template-columns: 1fr 1fr; gap: 24px; margin-top: 20px;">

Inline Directive Splitting

The formatter detects Edge directives that are inline with other content and automatically splits them to their own lines on save.

Before (directives mixed with content):

              Submit@end
              Create Custom Field@end
<h1>Title</h1>@end
@if(user)<div>Welcome</div>

After (each directive on its own line):

              Submit
@end
              Create Custom Field
@end
<h1>Title</h1>
@end
@if(user)
  <div>Welcome</div>

This works for all block directives: @component, @slot, @if, @each, @unless, @forelse, @section, @stack, @push, @prepend, @else, @elseif, @end, @endsection, and more.

Broken HTML Tag Repair

The formatter automatically detects and fixes HTML tags that have been split across lines — a common issue when editors or copy-paste operations break closing > onto a new line.

Before:

<span style="color: #4ade80">Yes</span
>

</span
>

After:

<span style="color: #4ade80">Yes</span>

</span>

This handles all variations: </tag\n>, <tag attr="val"\n>, <tag\n/>, etc.

Smart Ternary Conversion

When a simple @if/@else/@end block has plain text values in both branches, the formatter automatically converts it to a cleaner ternary expression.

Before:

@if(theme?.pricing.is_free)
  Free
@else
  Paid
@end

After:

{{ theme?.pricing.is_free ? 'Free' : 'Paid' }}

What gets converted:

  • Both branches must be simple plain text (no HTML, no Edge directives, no expressions)
  • Each value must be short (max 40 characters)
  • Must have both @if and @else branches (no @elseif)

What does NOT get converted (stays as-is):

Pattern Why
@if(x) <span>Yes</span> @else <span>No</span> @end Contains HTML tags
@if(x) {{ val }} @else Other @end Contains Edge expressions
@if(x) Featured @end (no @else) Missing else branch
@if(x) Very long descriptive text... @else Other @end Value exceeds 40 chars
@if(x) A @elseif(y) B @else C @end Has @elseif (not a simple binary)

Auto-Close Snippets

Type @ and the completion menu shows all Edge directives with auto-closing snippets:

You type Inserts
@component @component('name') ... @end
@slot @slot('name') ... @end
@if @if(condition) ... @end
@each @each(item in collection) ... @end
@unless @unless(condition) ... @end
@section @section('name') ... @endsection
@stack @stack('name') ... @end
@push @push('name') ... @end
@include @include('partial') (no closing tag)

Press Tab to jump between the snippet placeholders (name → body).

Script and Style Block Formatting

CSS inside <style> and JavaScript inside <script> blocks are re-indented properly:

<style>
  .floating-btn {
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 1030;
  }
</style>

Error Diagnostics: Directives Inside HTML Tags

The extension shows real-time errors (red squiggly underlines) when block directives like @if, @end, @each, etc. are used inside HTML tag attributes. This is a common mistake that breaks rendering.

Example — these will be flagged as errors:

{{-- ERROR: @if and @end are inside the <input> tag --}}
<input type="button"
  value="@if(condition) match @end"
  name="submit"
  @if(condition) onclick="doSomething()" @end
/>

Correct approach — use ternary expressions:

<input type="button"
  value="{{ condition ? 'match' : '' }}"
  name="submit"
  {{ condition ? 'onclick=doSomething()' : '' }}
/>

What gets flagged:

  • @if(...), @elseif(...), @else, @end inside <tag ... >
  • @each(...), @unless(...), @component(...), @slot(...) inside tags
  • Works for both single-line and multi-line HTML tags

What does NOT get flagged (legitimate usage):

  • @if / @end between HTML tags (normal Edge flow control)
  • {{ expression }} inside HTML attributes (correct approach)
  • Edge comments {{-- --}}

Code Folding

Fold and unfold sections of your Edge templates to focus on what matters.

What Can Be Folded

Construct Example Folds to
Components @component('layout') ... @end @component('layout') ...
Slots @slot('body') ... @end @slot('body') ...
Conditionals @if(user) ... @end @if(user) ...
Individual branches @if → @elseif, @elseif → @else, @else → @end Each branch folds independently
Loops @each(item in items) ... @end @each(item in items) ...
Sections @section('content') ... @endsection @section('content') ...
Multi-line comments {{-- ... --}} {{-- ...
HTML elements <div> ... </div> <div> ...

Folding Keyboard Shortcuts

Shortcut Action
Ctrl+Shift+[ Fold at cursor
Ctrl+Shift+] Unfold at cursor
Ctrl+K Ctrl+0 Fold all
Ctrl+K Ctrl+J Unfold all
Ctrl+K Ctrl+1 Fold level 1 (top-level blocks)
Ctrl+K Ctrl+2 Fold level 2
Ctrl+K Ctrl+3 Fold level 3 (deeper nesting)

Conditional Branch Folding

Each branch in an @if/@elseif/@else chain folds independently:

@if(user.isAdmin)        ← fold this section
  <AdminPanel />
@elseif(user.isMod)      ← fold this section separately
  <ModPanel />
@else                     ← fold this section separately
  <UserPanel />
@end

HTML Comment → Edge Comment Conversion

HTML comments (<!-- -->) are sent to the browser and visible in the page source. Edge comments ({{-- --}}) are stripped during rendering — they never reach the client.

Automatic Conversion on Save

Enable this setting and every <!-- comment --> in your .edge files is automatically converted to {{-- comment --}} when you save:

// .vscode/settings.json
{
  "edge.format.convertHtmlCommentsOnSave": true
}

Before save:

<!-- Page Title And Screens -->
<div class="container">
  <!-- User Profile Section -->
  <h1>{{ user.name }}</h1>
</div>

After save:

{{-- Page Title And Screens --}}
<div class="container">
  {{-- User Profile Section --}}
  <h1>{{ user.name }}</h1>
</div>

Manual Conversion (One-Time)

You can also run the conversion on-demand:

  1. Command Palette: Ctrl+Shift+P → "Edge: Convert HTML Comments to Edge Comments"
  2. Right-click context menu: Right-click in a .edge file → "Edge: Convert HTML Comments to Edge Comments"

Both methods handle single-line and multi-line HTML comments, and skip any comments already using Edge syntax.


Supported Directives

Block Directives

These create indented blocks and are foldable:

Directive Closed by Description
@component('...') @end Include a component with slots
@slot('...') @end Define a named content slot
@if(...) @end Conditional rendering
@unless(...) @end Inverse conditional
@each(item in list) @end Loop over a collection
@forelse(item in list) @end Loop with empty-state fallback
@section('...') @endsection Define a layout section

Mid-Block Directives

These split a block into sub-sections:

Directive Context
@elseif(...) Alternative condition in @if block
@else Fallback branch in @if or @unless block

Inline Directives

These do not create blocks:

Directive Description
@include('...') Include a partial template
@set(name = value) Set a template variable
@inject(...) Inject a service
@break Break from a loop
@continue Skip to next loop iteration

Expressions

Syntax Description
{{ expr }} Escaped output (XSS-safe)
{{{ expr }}} Raw/unescaped HTML output
{{-- comment --}} Template comment (not rendered)

Syntax Highlighting

The extension provides full syntax highlighting for:

  • Edge directives — @component, @if, @each, etc. highlighted as control keywords
  • Expressions — {{ }} and {{{ }}} with operator and literal highlighting
  • Comments — {{-- --}} highlighted as comments
  • Embedded CSS — Full CSS highlighting inside <style> blocks
  • Embedded JavaScript — Full JS highlighting inside <script> blocks
  • HTML — Standard HTML tag and attribute highlighting

Expression Operators

The following operators are recognized and highlighted inside {{ }}:

?.  ??  ===  !==  ==  !=  >=  <=  >  <
&&  ||  !  ?  :  +  -  *  /  %

Auto-Indent on Type

When you finish typing @end or @endsection, the extension automatically re-indents the line to match the indentation of the corresponding opening directive.

Example: Type @end anywhere — it snaps to the correct indentation level:

@if(user)
  <h1>Hello</h1>
      @end   ← you type this

Becomes:

@if(user)
  <h1>Hello</h1>
@end           ← auto-aligned

Configuration

All settings are under the edge.format.* namespace.

Setting Type Default Description
edge.format.enable boolean true Enable/disable the formatter
edge.format.indentSize number 2 Spaces per indentation level
edge.format.wrapLineLength number 120 Max line length for attribute wrapping
edge.format.preserveNewLines boolean true Keep existing blank lines
edge.format.maxPreserveNewLines number 2 Max consecutive blank lines allowed
edge.format.convertHtmlCommentsOnSave boolean false Auto-convert <!-- --> to {{-- --}} on save

Example Configuration

// .vscode/settings.json
{
  "edge.format.enable": true,
  "edge.format.indentSize": 4,
  "edge.format.preserveNewLines": true,
  "edge.format.maxPreserveNewLines": 1,
  "edge.format.convertHtmlCommentsOnSave": true,
  "[edge]": {
    "editor.defaultFormatter": "foduu.edge-template-formatter",
    "editor.formatOnSave": true,
    "editor.tabSize": 4
  }
}

Auto-Closing Pairs

The extension auto-closes these pairs as you type:

You type Auto-inserted
{{ }}
{{{ }}}
{{-- --}}
{ }
[ ]
( )
< >
" "
' '

Contributing

Contributions are welcome! Please open an issue or submit a PR.

Development Setup

# Clone the repo
git clone https://github.com/nicekid1/edge-template-formatter.git
cd edge-template-formatter

# Install dependencies
npm install

# Compile TypeScript
npm run compile

# Launch extension in development mode
# Press F5 in VS Code to open the Extension Development Host

Project Structure

edge-formatter-vscode/
  src/
    extension.ts          # Extension entry point, registers all providers
    formatter.ts          # Document & range formatting logic
    folding.ts            # Programmatic folding range provider
    completions.ts        # Auto-close snippet completion provider
    diagnostics.ts        # Real-time error/warning diagnostics
  syntaxes/
    edge.tmLanguage.json  # TextMate grammar for syntax highlighting
  language-configuration.json  # Brackets, comments, indentation rules
  package.json           # Extension manifest

Build & Package

# Compile
npm run compile

# Watch mode (auto-recompile on changes)
npm run watch

# Package as .vsix
npx @vscode/vsce package

# Publish to marketplace
npx @vscode/vsce publish

Troubleshooting

Formatter not working?

  1. Check file type — Ensure VS Code recognizes the file as "Edge Template". Look at the bottom-right status bar — it should show "Edge".
  2. Check default formatter — Set the default formatter for .edge files:
    "[edge]": {
      "editor.defaultFormatter": "foduu.edge-template-formatter"
    }
    
  3. Check if enabled — Ensure edge.format.enable is true in settings.
  4. Reload VS Code — After installing or updating, run Ctrl+Shift+P → "Reload Window".

Folding arrows not showing?

  1. Enable folding — Check that editor.folding is true (it is by default).
  2. Show fold controls — Set editor.showFoldingControls to "always" to always show fold arrows in the gutter:
    "editor.showFoldingControls": "always"
    

Format on Save not working?

Ensure both settings are configured:

"editor.formatOnSave": true,
"[edge]": {
  "editor.defaultFormatter": "foduu.edge-template-formatter"
}

Version Log

v0.3.0 — 2026-03-20

New Features:

  • Broken HTML Tag Repair: Automatically fixes HTML tags split across lines (</span\n> → </span>) during formatting. Handles closing tags, self-closing tags, and tags with attributes.
  • Smart Ternary Conversion: Auto-converts simple @if(condition) Value @else OtherValue @end blocks to {{ condition ? 'Value' : 'OtherValue' }} when both branches are plain text. Skips complex blocks with HTML, expressions, or multiple lines.

Improvements:

  • Formatter pipeline now runs 5 steps in order: broken tag repair → inline directive splitting → multi-line attribute joining → ternary conversion → indentation formatting
  • Ternary conversion is smart about quoting: numbers stay unquoted, values with single quotes get double-quoted

v0.2.0 — 2026-03-20

New Features:

  • Error Diagnostics — Directives Inside HTML Tags: Real-time red error underlines when @if, @end, @each, etc. are used inside HTML tag attributes (<tag @if(x)...>). Suggests ternary expressions as the correct approach.
  • Warning Diagnostics — Inline Directives Mixed with HTML: Yellow warnings when Edge directives share a line with HTML tags (e.g., <div>@include('partial')</div>). Encourages each directive to be on its own line.
  • Auto-Close Snippets: Type @ to get snippet completions for all block directives (@if, @component, @slot, @each, @unless, @section, @stack, @push, @include) with auto-inserted @end and Tab-stop navigation.
  • HTML Comment → Edge Comment Conversion on Save: New setting edge.format.convertHtmlCommentsOnSave auto-converts <!-- --> to {{-- --}} on save so comments never ship to the browser.
  • HTML Comment Conversion Command: Manual one-click command via Command Palette or right-click context menu.
  • Inline Directive Splitting on Save: Automatically moves @if, @end, @slot, @component, etc. to their own lines when mixed inline with other content.
  • Multi-line Attribute Joining: Collapses multi-line HTML attributes (like style="...") into single lines on format.
  • Programmatic Code Folding: Stack-based folding for @slot→@end, @if→@else→@end (each branch folds independently), @each→@end, multi-line {{-- --}} comments, and HTML elements.

Improvements:

  • Diagnostics run in real-time as you type (no save required)
  • Files with errors show red in VS Code explorer sidebar
  • Files with warnings show yellow in VS Code explorer sidebar
  • Smart detection skips <script>/<style> blocks to avoid false positives on @media, @keyframes, etc.

v0.1.0 — 2026-03-20

Initial Release:

  • Syntax highlighting for Edge directives, expressions, and embedded HTML/CSS/JS
  • Document formatting with proper indentation for nested Edge blocks
  • Auto-indent on type for @end / @endsection
  • Language configuration with comment toggling, bracket matching, and auto-closing pairs
  • Basic code folding support
  • Configurable indent size, line length, and blank line handling
  • Status bar indicator for .edge files

Built with Love and Peace by FODUU

This extension is built with love and peace by Studio FODUU — making development easier, one tool at a time.

Visit us at https://www.foduu.com

Acknowledgements

A big thanks and shoutout to the Edge.js team for creating such an elegant templating engine for the AdonisJS ecosystem. This extension wouldn't exist without their fantastic work.


License

MIT — see LICENSE.txt

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft