# WRNexus Language Support 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. Typed declarations work across props, state, and functions: ```wrn component UserCard { types { interface User { id: string; name: string } } props { user: User compact: boolean = false } state selected: boolean = false functions { function select(user: User): void { selected = true } } view {
{user.name}
} } ``` The extension shows declared prop types and reports missing required props and incompatible values. Typed prop and state expressions passed into nested components retain their declared type. ## Installation Search for **WRNexus Language Support** in the VS Code Extensions view or run: ```text ext install wrnexus.wrnexus ``` 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-.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 The extension provides highlighting for WRNexus declarations and embedded languages. Supported top-level declarations: ```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 { } ``` Put `// @required` immediately above a prop when callers must provide it while retaining a typed runtime fallback. `propName = undefined` is also treated as required when no fallback is appropriate. The editor shows required props first in completion lists and reports an error when a component mount omits one. Prop types are inferred from defaults, and string options used in component comparisons are offered as completion choices. 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 {

User {id}

} } ``` 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 { } } ``` 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 {
{content}
} } ``` 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 {

{count}

} } ``` 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 { } } ``` 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
``` ```wrn
``` ```wrn
``` ### Document events ```wrn
``` ```wrn
``` 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 { } } ``` ## Conditional classes Use `class:` to toggle CSS classes reactively: ```wrn ``` The expression is evaluated whenever its reactive dependencies change. ## Event bindings Standard element events: ```wrn ``` ```wrn ``` ```wrn
``` 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
Visible when open is true
``` ### Reactive loops ```wrn ``` ### Reactive text ```wrn ``` ### Dynamic attributes ```wrn ``` ## 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]": { "editor.defaultFormatter": "wrnexus.wrnexus", "editor.formatOnSave": true } ``` 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 } ``` ## Troubleshooting language detection Files ending in `.wrn` should show `WRNexus` in the VS Code status bar. If an older workspace setting maps `*.wrn` to the legacy `wire` language ID, replace it with: ```json "files.associations": { "*.wrn": "wrn" } ``` Then run **Developer: Reload Window**. The extension also repairs open `.wrn` documents that VS Code classified as Plain Text or as the legacy `wire` language. ## Privacy 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 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 ``` This creates: ```text wrnexus-.vsix ``` Install the local package: ```bash code --install-extension ./wrnexus-.vsix --force ``` Open the extension folder in VS Code and press F5 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.