release: WRNexusJS 0.2.32
This commit is contained in:
+756
-47
@@ -1,54 +1,614 @@
|
||||
# WRNexus Language Support
|
||||
|
||||
Language support for [WRNexus](https://wrnexusjs.dev) `.wrn` files — the SSR-first,
|
||||
Bun-powered full-stack framework.
|
||||
Complete VS Code language support for [WRNexus](https://wrnexusjs.dev) `.wrn` files.
|
||||
|
||||
WRNexus is an SSR-first, Bun-powered full-stack framework with reactive components, layouts, colocated APIs, browser functions, lifecycle hooks, state watchers, client-side navigation, and reusable UI components.
|
||||
|
||||
## Installation
|
||||
|
||||
After the first Marketplace release, search for **WRNexus Language Support** in
|
||||
VS Code or run:
|
||||
Search for **WRNexus Language Support** in the VS Code Extensions view or run:
|
||||
|
||||
```text
|
||||
ext install wrnexus.wrnexus
|
||||
```
|
||||
|
||||
For a local package, open the Command Palette, choose **Extensions: Install from
|
||||
VSIX**, and select the generated `wrnexus-<version>.vsix` file.
|
||||
For a local build:
|
||||
|
||||
1. Package the extension:
|
||||
|
||||
```bash
|
||||
bun run package
|
||||
```
|
||||
|
||||
2. Open the VS Code Command Palette.
|
||||
3. Select **Extensions: Install from VSIX**.
|
||||
4. Choose the generated `wrnexus-<version>.vsix` file.
|
||||
|
||||
You can also install it from the terminal:
|
||||
|
||||
```bash
|
||||
code --install-extension ./wrnexus-0.2.7.vsix --force
|
||||
```
|
||||
|
||||
Reload VS Code after installation:
|
||||
|
||||
```text
|
||||
Developer: Reload Window
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- **Syntax highlighting** ("color-full code"). Keywords (`page`, `component`,
|
||||
`state`, `view`, `api`, `realtime`, …) plus **embedded highlighting** for the
|
||||
languages inside each block:
|
||||
- `view { … }` → HTML, with `{expr}` interpolation and `{t:key}` translations
|
||||
and `@event="…"` bindings picked out.
|
||||
- `style { … }` → CSS.
|
||||
- `functions { … }`, `api … { … }`, `ssr`/`client`, `realtime on(…) { … }` → TypeScript.
|
||||
- **WrNexus attributes in distinct colors.** A grammar injection recolors the
|
||||
framework's own attributes so they pop even inside plain HTML: `@event`
|
||||
bindings and `{t:…}` in one accent, runtime directives (`data-component`,
|
||||
`data-for`, `data-show`, `data-text`, `data-scope`, `data-slot`, `data-on-*`,
|
||||
`data-wire-*`) in another. Default colors ship with the extension; change them
|
||||
under `editor.tokenColorCustomizations` (scopes
|
||||
`entity.other.attribute-name.wrn.directive` and `…wire.event`).
|
||||
- **Diagnostics.** Parse errors from the real `@wrnexus/compiler` are shown inline
|
||||
as you type, anchored to the exact offset.
|
||||
- **Formatting.** Format Document and format-on-save normalize WRN block, HTML,
|
||||
CSS, and function indentation without rewriting application expressions.
|
||||
- **Snippets.** `page`, `component`, `view`, `state`, `props`, `seo`, `api`,
|
||||
`ssr`, `client`, `realtime`, `functions`, `style`, plus view helpers `mount`,
|
||||
`for`, `show`, `t`.
|
||||
- **Completions.** Block keywords at file scope, `data-*` runtime attributes and
|
||||
`@event` bindings inside a `view`, and HTTP methods after `api`.
|
||||
### Syntax highlighting
|
||||
|
||||
## Settings
|
||||
The extension provides highlighting for WRNexus declarations and embedded languages.
|
||||
|
||||
| Setting | Default | Description |
|
||||
| ---------------------------- | ------- | ----------------------------------------- |
|
||||
| `wrnexus.diagnostics.enable` | `true` | Show parse errors for `.wrn` files. |
|
||||
| `wrnexus.format.enable` | `true` | Enable the built-in formatter for `.wrn`. |
|
||||
Supported top-level declarations:
|
||||
|
||||
To format automatically when saving, add this to VS Code settings:
|
||||
```wrn
|
||||
page HomePage {
|
||||
}
|
||||
|
||||
component UserCard {
|
||||
}
|
||||
|
||||
layout PublicLayout {
|
||||
}
|
||||
```
|
||||
|
||||
Supported WRNexus blocks include:
|
||||
|
||||
```wrn
|
||||
props {
|
||||
}
|
||||
|
||||
state count = 0
|
||||
|
||||
seo {
|
||||
}
|
||||
|
||||
functions {
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
}
|
||||
|
||||
watch count {
|
||||
}
|
||||
|
||||
view {
|
||||
}
|
||||
|
||||
style {
|
||||
}
|
||||
|
||||
api GET /api/users {
|
||||
}
|
||||
|
||||
ssr {
|
||||
}
|
||||
|
||||
client {
|
||||
}
|
||||
|
||||
realtime chat {
|
||||
}
|
||||
```
|
||||
|
||||
Embedded language highlighting:
|
||||
|
||||
- `view { ... }` uses HTML highlighting.
|
||||
- `style { ... }` uses CSS highlighting.
|
||||
- `functions { ... }` uses TypeScript highlighting.
|
||||
- Lifecycle hook bodies use TypeScript highlighting.
|
||||
- Watcher bodies use TypeScript highlighting.
|
||||
- API, SSR, client, and realtime bodies use TypeScript highlighting.
|
||||
- `{expression}` interpolation uses TypeScript expression highlighting.
|
||||
|
||||
### Pages
|
||||
|
||||
Create route pages with layouts, SEO metadata, state, APIs, and views:
|
||||
|
||||
```wrn
|
||||
page UserPage {
|
||||
layout = "public"
|
||||
|
||||
state id = ctx.params.id
|
||||
|
||||
seo {
|
||||
title = "User profile"
|
||||
description = "View user information"
|
||||
}
|
||||
|
||||
view {
|
||||
<main>
|
||||
<h1>User {id}</h1>
|
||||
</main>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Dynamic route parameters are available through:
|
||||
|
||||
```wrn
|
||||
state id = ctx.params.id
|
||||
```
|
||||
|
||||
For a route such as:
|
||||
|
||||
```text
|
||||
pages/users/[id].wrn
|
||||
```
|
||||
|
||||
autocomplete suggests:
|
||||
|
||||
```text
|
||||
id
|
||||
ctx.params.id
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
Create reusable reactive components:
|
||||
|
||||
```wrn
|
||||
component Counter {
|
||||
state count = 0
|
||||
|
||||
view {
|
||||
<button @click="count++">
|
||||
Count: {count}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Components support:
|
||||
|
||||
- props
|
||||
- reactive state
|
||||
- browser functions
|
||||
- lifecycle hooks
|
||||
- state watchers
|
||||
- event handlers
|
||||
- conditional classes
|
||||
- reactive attributes
|
||||
- reactive loops
|
||||
- conditional visibility
|
||||
|
||||
### Layouts
|
||||
|
||||
Create reusable layouts:
|
||||
|
||||
```wrn
|
||||
layout PublicLayout {
|
||||
view {
|
||||
<header>
|
||||
<nav>Navigation</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{content}
|
||||
</main>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Layouts can also use state, props, functions, lifecycle hooks, and watchers.
|
||||
|
||||
## Browser functions
|
||||
|
||||
Functions declared inside a component or layout are available to browser events, lifecycle hooks, and watchers.
|
||||
|
||||
```wrn
|
||||
component Counter {
|
||||
state count = 0
|
||||
|
||||
functions {
|
||||
function increment() {
|
||||
count += 1
|
||||
}
|
||||
|
||||
function reset() {
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
|
||||
view {
|
||||
<button @click="increment()">
|
||||
Increment
|
||||
</button>
|
||||
|
||||
<button @click="reset()">
|
||||
Reset
|
||||
</button>
|
||||
|
||||
<p>{count}</p>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Functions may use browser APIs:
|
||||
|
||||
```wrn
|
||||
functions {
|
||||
function scrollToTop() {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Asynchronous functions are also supported:
|
||||
|
||||
```wrn
|
||||
functions {
|
||||
async function loadUsers() {
|
||||
const response = await fetch("/api/users")
|
||||
const users = await response.json()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
Components and layouts support three lifecycle hooks:
|
||||
|
||||
```wrn
|
||||
lifecycle {
|
||||
mount {
|
||||
}
|
||||
|
||||
update {
|
||||
}
|
||||
|
||||
unmount {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `mount`
|
||||
|
||||
Runs once after the component is connected to the page and hydrated.
|
||||
|
||||
```wrn
|
||||
lifecycle {
|
||||
mount {
|
||||
console.log("Component mounted")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use it to:
|
||||
|
||||
- read browser state
|
||||
- initialize third-party libraries
|
||||
- register global event listeners
|
||||
- start timers
|
||||
- perform initial browser-only work
|
||||
|
||||
### `update`
|
||||
|
||||
Runs after reactive state changes.
|
||||
|
||||
Multiple synchronous state changes are batched into one update cycle.
|
||||
|
||||
```wrn
|
||||
lifecycle {
|
||||
update {
|
||||
console.log("Component state updated")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `unmount`
|
||||
|
||||
Runs before the component is removed.
|
||||
|
||||
```wrn
|
||||
lifecycle {
|
||||
unmount {
|
||||
console.log("Component removed")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use it to:
|
||||
|
||||
- remove global event listeners
|
||||
- clear timers
|
||||
- disconnect observers
|
||||
- release browser resources
|
||||
- clean up third-party libraries
|
||||
|
||||
Lifecycle cleanup also runs during WRNexus client-side navigation.
|
||||
|
||||
## State watchers
|
||||
|
||||
Watch one declared state value:
|
||||
|
||||
```wrn
|
||||
component Menu {
|
||||
state open = false
|
||||
|
||||
watch open {
|
||||
console.log("Current value:", value)
|
||||
console.log("Previous value:", previous)
|
||||
}
|
||||
|
||||
view {
|
||||
<button @click="open = !open">
|
||||
Toggle menu
|
||||
</button>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Watcher variables:
|
||||
|
||||
| Variable | Description |
|
||||
| ---------- | -------------------- |
|
||||
| `value` | Current state value |
|
||||
| `previous` | Previous state value |
|
||||
|
||||
A watcher runs only when its declared state changes.
|
||||
|
||||
Invalid watcher declarations are reported:
|
||||
|
||||
```wrn
|
||||
watch missingState {
|
||||
}
|
||||
```
|
||||
|
||||
The editor reports that `missingState` has not been declared.
|
||||
|
||||
## Window and document events
|
||||
|
||||
WRNexus supports events attached directly to `window` and `document`.
|
||||
|
||||
### Window events
|
||||
|
||||
```wrn
|
||||
<div @window:scroll="updateScrollPosition()">
|
||||
</div>
|
||||
```
|
||||
|
||||
```wrn
|
||||
<div @window:resize="updateViewportSize()">
|
||||
</div>
|
||||
```
|
||||
|
||||
```wrn
|
||||
<div @window:keydown="handleKeyboardShortcut()">
|
||||
</div>
|
||||
```
|
||||
|
||||
### Document events
|
||||
|
||||
```wrn
|
||||
<div @document:click="closeMenu()">
|
||||
</div>
|
||||
```
|
||||
|
||||
```wrn
|
||||
<div @document:visibilitychange="handleVisibilityChange()">
|
||||
</div>
|
||||
```
|
||||
|
||||
Global event listeners created manually inside `mount` should be removed inside `unmount`.
|
||||
|
||||
## Complete BackToTop example
|
||||
|
||||
```wrn
|
||||
component BackToTop {
|
||||
state visible = false
|
||||
|
||||
functions {
|
||||
function updateBackToTopVisibility() {
|
||||
visible = window.scrollY > 500
|
||||
}
|
||||
|
||||
function scrollToTop() {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
mount {
|
||||
updateBackToTopVisibility()
|
||||
|
||||
window.addEventListener(
|
||||
"scroll",
|
||||
updateBackToTopVisibility,
|
||||
{ passive: true }
|
||||
)
|
||||
}
|
||||
|
||||
unmount {
|
||||
window.removeEventListener(
|
||||
"scroll",
|
||||
updateBackToTopVisibility
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
watch visible {
|
||||
console.log(
|
||||
"BackToTop visibility changed:",
|
||||
value,
|
||||
previous
|
||||
)
|
||||
}
|
||||
|
||||
view {
|
||||
<button
|
||||
type="button"
|
||||
@click="scrollToTop()"
|
||||
aria-label="Back to top"
|
||||
class="fixed bottom-5 right-5"
|
||||
class:pointer-events-none="!visible"
|
||||
class:translate-y-4="!visible"
|
||||
class:opacity-0="!visible"
|
||||
class:pointer-events-auto="visible"
|
||||
class:translate-y-0="visible"
|
||||
class:opacity-100="visible"
|
||||
>
|
||||
Back to top
|
||||
</button>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Conditional classes
|
||||
|
||||
Use `class:<class-name>` to toggle CSS classes reactively:
|
||||
|
||||
```wrn
|
||||
<button
|
||||
class:opacity-100="visible"
|
||||
class:pointer-events-auto="visible"
|
||||
class:opacity-0="!visible"
|
||||
class:pointer-events-none="!visible"
|
||||
>
|
||||
Action
|
||||
</button>
|
||||
```
|
||||
|
||||
The expression is evaluated whenever its reactive dependencies change.
|
||||
|
||||
## Event bindings
|
||||
|
||||
Standard element events:
|
||||
|
||||
```wrn
|
||||
<button @click="submitForm()">
|
||||
Submit
|
||||
</button>
|
||||
```
|
||||
|
||||
```wrn
|
||||
<input @input="query = event.target.value" />
|
||||
```
|
||||
|
||||
```wrn
|
||||
<form @submit="handleSubmit()">
|
||||
</form>
|
||||
```
|
||||
|
||||
Supported completion suggestions include:
|
||||
|
||||
- `@click`
|
||||
- `@input`
|
||||
- `@change`
|
||||
- `@submit`
|
||||
- `@focus`
|
||||
- `@blur`
|
||||
- `@keydown`
|
||||
- `@keyup`
|
||||
- `@mouseenter`
|
||||
- `@mouseleave`
|
||||
- `@window:scroll`
|
||||
- `@window:resize`
|
||||
- `@window:keydown`
|
||||
- `@document:click`
|
||||
- `@document:visibilitychange`
|
||||
|
||||
## Reactive directives
|
||||
|
||||
### Conditional visibility
|
||||
|
||||
```wrn
|
||||
<div data-show="open">
|
||||
Visible when open is true
|
||||
</div>
|
||||
```
|
||||
|
||||
### Reactive loops
|
||||
|
||||
```wrn
|
||||
<ul>
|
||||
<li data-for="user in users">
|
||||
{user.name}
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
### Reactive text
|
||||
|
||||
```wrn
|
||||
<span data-text="message"></span>
|
||||
```
|
||||
|
||||
### Dynamic attributes
|
||||
|
||||
```wrn
|
||||
<button disabled="{loading}">
|
||||
Save
|
||||
</button>
|
||||
```
|
||||
|
||||
## Diagnostics
|
||||
|
||||
The extension provides two diagnostic layers.
|
||||
|
||||
### Editor diagnostics
|
||||
|
||||
Fast local validation checks:
|
||||
|
||||
- invalid root declarations
|
||||
- unknown page, component, or layout members
|
||||
- unbalanced braces, brackets, and parentheses
|
||||
- unclosed strings
|
||||
- invalid HTML closing tags
|
||||
- missing HTML closing tags
|
||||
- invalid lifecycle hooks
|
||||
- duplicate lifecycle hooks
|
||||
- duplicate lifecycle blocks
|
||||
- undeclared watched states
|
||||
- missing watcher bodies
|
||||
- invalid layout usage
|
||||
- missing view blocks
|
||||
|
||||
### Compiler diagnostics
|
||||
|
||||
The extension bundles the real WRNexus compiler and validates `.wrn` files as you type.
|
||||
|
||||
Compiler errors are attached to the reported source offset whenever available.
|
||||
|
||||
Disable diagnostics with:
|
||||
|
||||
```json
|
||||
"wrnexus.diagnostics.enable": false
|
||||
```
|
||||
|
||||
## Formatting
|
||||
|
||||
The built-in formatter supports:
|
||||
|
||||
- page, component, and layout indentation
|
||||
- functions and nested function bodies
|
||||
- lifecycle blocks
|
||||
- watcher blocks
|
||||
- multiline function calls
|
||||
- object literals
|
||||
- HTML elements
|
||||
- multiline HTML attributes
|
||||
- conditional class directives
|
||||
- window and document events
|
||||
- CSS blocks
|
||||
- API blocks
|
||||
|
||||
Format a document using:
|
||||
|
||||
```text
|
||||
Shift+Alt+F
|
||||
```
|
||||
|
||||
Enable format-on-save:
|
||||
|
||||
```json
|
||||
"[wrn]": {
|
||||
@@ -57,29 +617,178 @@ To format automatically when saving, add this to VS Code settings:
|
||||
}
|
||||
```
|
||||
|
||||
Disable the formatter:
|
||||
|
||||
```json
|
||||
"wrnexus.format.enable": false
|
||||
```
|
||||
|
||||
Configure preferred line width:
|
||||
|
||||
```json
|
||||
"wrnexus.formatting.printWidth": 100
|
||||
```
|
||||
|
||||
## Autocomplete
|
||||
|
||||
Autocomplete is available for:
|
||||
|
||||
- pages
|
||||
- components
|
||||
- layouts
|
||||
- state declarations
|
||||
- props
|
||||
- views
|
||||
- SEO metadata
|
||||
- functions
|
||||
- lifecycle hooks
|
||||
- watchers
|
||||
- declared state names
|
||||
- declared props
|
||||
- declared functions
|
||||
- watcher variables
|
||||
- route parameters
|
||||
- context values
|
||||
- standard events
|
||||
- window events
|
||||
- document events
|
||||
- reactive attributes
|
||||
- conditional classes
|
||||
|
||||
After typing:
|
||||
|
||||
```wrn
|
||||
watch
|
||||
```
|
||||
|
||||
the extension suggests declared state names.
|
||||
|
||||
Inside a watcher, it suggests:
|
||||
|
||||
```text
|
||||
value
|
||||
previous
|
||||
```
|
||||
|
||||
Declared component functions are suggested as callable snippets:
|
||||
|
||||
```text
|
||||
updateVisibility()
|
||||
scrollToTop()
|
||||
```
|
||||
|
||||
## Go to definition
|
||||
|
||||
Use Ctrl+Click or **Go to Definition** for supported WRNexus symbols.
|
||||
|
||||
The extension can navigate to component declarations and locally declared functions when supported by the definition provider.
|
||||
|
||||
## Snippets
|
||||
|
||||
Useful snippet prefixes include:
|
||||
|
||||
| Prefix | Purpose |
|
||||
| ------------------------ | ------------------------------------- |
|
||||
| `wrn-page` | Create a page |
|
||||
| `wrn-dynamic-page` | Create a dynamic route page |
|
||||
| `wrn-component` | Create a component |
|
||||
| `wrn-reactive-component` | Create a reactive component |
|
||||
| `wrn-layout` | Create a layout |
|
||||
| `wrn-state` | Declare state |
|
||||
| `wrn-functions` | Create a functions block |
|
||||
| `wrn-function` | Create a function |
|
||||
| `wrn-async-function` | Create an async function |
|
||||
| `wrn-lifecycle` | Create all lifecycle hooks |
|
||||
| `wrn-mount` | Create a mount hook |
|
||||
| `wrn-update` | Create an update hook |
|
||||
| `wrn-unmount` | Create an unmount hook |
|
||||
| `wrn-watch` | Create a watcher |
|
||||
| `wrn-window-scroll` | Add a window scroll event |
|
||||
| `wrn-window-resize` | Add a window resize event |
|
||||
| `wrn-document-event` | Add a document event |
|
||||
| `wrn-class-if` | Add a conditional class |
|
||||
| `wrn-class-toggle` | Toggle two classes |
|
||||
| `wrn-back-to-top` | Create a complete BackToTop component |
|
||||
|
||||
## Settings
|
||||
|
||||
| Setting | Default | Description |
|
||||
| ------------------------------- | ------- | -------------------------------------- |
|
||||
| `wrnexus.diagnostics.enable` | `true` | Enable editor and compiler diagnostics |
|
||||
| `wrnexus.format.enable` | `true` | Enable the built-in formatter |
|
||||
| `wrnexus.formatting.printWidth` | `100` | Preferred formatter line width |
|
||||
|
||||
Recommended VS Code configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"[wrn]": {
|
||||
"editor.defaultFormatter": "wrnexus.wrnexus",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.tabSize": 4,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.snippetSuggestions": "top"
|
||||
},
|
||||
"wrnexus.diagnostics.enable": true,
|
||||
"wrnexus.format.enable": true,
|
||||
"wrnexus.formatting.printWidth": 100
|
||||
}
|
||||
```
|
||||
|
||||
## Privacy
|
||||
|
||||
The extension does not collect telemetry and does not send source code or usage
|
||||
data over the network. Formatting, completion, and diagnostics run locally.
|
||||
The extension does not collect telemetry.
|
||||
|
||||
It does not send source code, diagnostics, formatting data, or usage information over the network.
|
||||
|
||||
Syntax highlighting, formatting, autocomplete, snippets, definition navigation, and diagnostics run locally.
|
||||
|
||||
## Development
|
||||
|
||||
Diagnostics use a bundled copy of the compiler. Build and validate everything
|
||||
after changing the extension or `@wrnexus/compiler`:
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
Rebuild the bundled compiler:
|
||||
|
||||
```bash
|
||||
bun run build:compiler
|
||||
```
|
||||
|
||||
Validate the extension:
|
||||
|
||||
```bash
|
||||
bun run check
|
||||
```
|
||||
|
||||
Package a VSIX:
|
||||
|
||||
```bash
|
||||
bun run package
|
||||
```
|
||||
|
||||
`bun run package` creates `wrnexus-<version>.vsix`. The extension still
|
||||
highlights, provides snippets, and completes without the compiler bundle; only
|
||||
inline error reporting requires it.
|
||||
This creates:
|
||||
|
||||
Open this folder in VS Code and press <kbd>F5</kbd> to launch an Extension
|
||||
Development Host, then open any `.wrn` file.
|
||||
```text
|
||||
wrnexus-<version>.vsix
|
||||
```
|
||||
|
||||
See the
|
||||
[Marketplace publishing guide](https://git.workroot.in/WorkRoot/WRNexusJS/src/branch/main/editors/vscode/PUBLISHING.md)
|
||||
for the release procedure.
|
||||
Install the local package:
|
||||
|
||||
```bash
|
||||
code --install-extension ./wrnexus-<version>.vsix --force
|
||||
```
|
||||
|
||||
Open the extension folder in VS Code and press <kbd>F5</kbd> to launch an Extension Development Host.
|
||||
|
||||
After changing the parser or compiler, always rebuild:
|
||||
|
||||
```bash
|
||||
bun run build:compiler
|
||||
```
|
||||
|
||||
Without the compiler bundle, syntax highlighting, snippets, formatting, and autocomplete continue to work, but compiler diagnostics are unavailable.
|
||||
|
||||
See the [Marketplace publishing guide](https://git.workroot.in/WorkRoot/WRNexusJS/src/branch/main/editors/vscode/PUBLISHING.md) for publishing instructions.
|
||||
|
||||
Reference in New Issue
Block a user