Compelem VSCode Extension
A VS Code extension that provides rich editing support for the
compelem component framework,
especially for the HTML-style markup written inside the `h`...` tag
templates of a component's render() function.
Features
1. Syntax Highlighting
- The HTML text inside
`h`...` functions is highlighted.
- The CSS text inside
`css`...` template functions is highlighted.
- All compelem directive functions (
show / ifTrue / ifElse / forEach / when / slot / html / classes / styles / model / bind ...) have individually
configurable colors.
- When the cursor is on a tag, the matching opening/closing tag name is
highlighted.
- Paired tags can be folded.
- Right-click formatting of the HTML markup template inside
`h`...`
functions is supported.
- Long tags are broken into one attribute per line; short elements
(e.g.
<span>Hello</span>) stay on a single line.
- When you want to keep the built-in TypeScript formatter as the default
document formatter, you can use the
Compelem: Format h... templates`
command.
- The number of indentation spaces can be set via
compelem.format.indentSize
(the default 0 means following the editor's tabSize).
3. IntelliSense & Completion
- Typing
<l- (or a PascalCase prefix) inside `h`...` functions lists
the components registered in the workspace.
- Typing
. on a component tag lists the component's props — including the
properties inherited via extends (e.g. color / size / disabled from a
base class) — and shows their type, default value, and @attrs
documentation.
- In any tag's attribute area, global HTML attributes are suggested:
class / style / name / id / title / hidden / tabindex / role / aria-label / aria-hidden / lang / dir / slot and data-* (accepting inserts class=""
with the caret between the quotes).
- Typing
@ on a tag suggests event names: native tags get their
tag-specific events (<slot> → slotchange, <input> → input / change,
<form> → submit, ...), component tags additionally get their @emits
events. Only the event name is inserted, so modifiers can follow.
- Typing
. after an event suggests event modifiers (self / stop / prevent / once / capture / passive / left / right / middle / ctrl / alt / shift / meta / esc / debounce / throttle), chainable (@click.stop.self)
with used modifiers de-duplicated.
- Typing
= after an event inserts the handler reference
(@click= → @click="${this.onClick}", modifiers never leak into the name).
- Typing an opening tag like
<div> automatically inserts </div> and moves
the cursor inside the element.
- Typing
<xx propname= on a component tag automatically inserts
"${this.value}".
- Typing
show / bind / classes / styles / model / html on any tag suggests a
tag-directive snippet such as ${show(this.visible)}; inside ${ ... },
text directives (forEach / when / ifTrue / ifElse / slot) are suggested
instead.
- Typing
@ outside templates suggests decorators: @computed / @watch / @query / @tag / @prop / @csscope, with auto-completion on acceptance.
4. Snippets
render → generates a render() that returns an `h`...` function
template containing a root <div>.
@watch → generates an empty @watch(...) method.
@computed → generates an empty @computed getter.
@csscope → generates an @csscope(Csscope.INNER) static getter template.
5. Diagnostics
- The
ref attribute must be an interpolation of a createRef member, e.g.
ref="${this.xxRef}".
- The
.xx directive attribute is allowed on any component tag — ce-xx
elements, dashed custom-element names (e.g. ce-xx, a-b-c), or
PascalCase components (e.g. <l-input .value="${this.xx}">); .xx on
<slot> is valid.
- The same directive (
show / bind / classes ...) may only appear once per
element.
- Decorator placement:
@csscope only on static getters, @watch only on
methods, @computed only on non-static getters, @emits / @tag only on
classes.
- Event names passed to
this.emit(...) must be declared in the class'
@emits decorator (ancestors are merged along the extends chain; classes
without any @emits on the chain are not checked).
@event="${this.onXxx}" values must be function references (method,
arrow-function field, or function field) — missing members and non-function
members are flagged.
6. Navigation
- Hold Ctrl and click a component tag (
l-xx / PascalCase) to jump to its
@tag class definition.
- Hold Ctrl and click a
this.xxx reference to jump to that member's
declaration.
- Hold Ctrl and click a CSS class to find its
.class selector in the style
files.
- For cross-file lookups, it falls back to VS Code's workspace symbol search.
Inside an h\`` template, Ctrl+/ normally inserts a JS line comment (//).
This extension already binds Ctrl+/ (Cmd+/ on macOS) to
compelem.toggleComment and Ctrl+Shift+/ (Cmd+Shift+/ on macOS) to
compelem.toggleBlockComment (TypeScript / TypeScript React files only),
toggling HTML comments instead — works out of the box. To override:
{
"key": "ctrl+/",
"command": "compelem.toggleComment",
"when": "editorTextFocus && (editorLangId == typescript || editorLangId == typescriptreact)"
}
- Line comment (
Ctrl+/): with no selection, the caret's line is wrapped as
<!-- ... --> (press again to unwrap). With a selection, each covered
line is wrapped individually (indentation kept); already-commented lines are
unwrapped.
- Block comment (
Ctrl+Shift+/): the whole selection is wrapped as
<!-- ... --> (multi-line selections wrap across lines; press again to
unwrap). With no selection, an empty <!-- --> is inserted.
- Code outside templates keeps VS Code's native
// / /* */ behavior.
License
Copyright (c) 2026 holyhigh2
| |