Jadren VS Code extension
Jadren Language Support registers .jdn files, syntax highlighting, file icons,
offline snippets/core completions, and a Language Server Protocol client.
Install a local development package
- Open VS Code.
- Run Extensions: Install from VSIX... from the Command Palette.
- Select the Jadren
.vsix package.
- Reload VS Code when requested.
- Open a
.jdn file and confirm that the language mode is Jadren.
The package also contributes the optional Jadren Dark workbench theme. Use
Preferences: Color Theme and select Jadren Dark when you want the full
Jadren neutral dark editor, terminal, panel and syntax palette. The extension does not
change the active theme automatically.
The extension setting jadren.lspPath selects the Jadren CLI executable. Its
default value is jadren, resolved from PATH.
{
"jadren.lspPath": "jadren",
"jadren.documentationLanguage": "en"
}
Editor API documentation is English by default. Set
jadren.documentationLanguage to sk when Slovak explanations are preferred;
the setting applies to offline completion, hover and signature help.
Current capabilities
- syntax highlighting;
- semantic-token mappings back to the same TextMate scopes, with stable
TextMate highlighting enabled by default so themes without semantic-token
colors still show keywords, functions, types, literals, and comments;
- language-scoped Jadren color defaults for keywords, functions, types,
variables, literals, strings, operators, and comments, independent of the
selected VS Code theme;
- the optional Jadren Dark color theme with matching editor, terminal and
workbench colors;
- diagnostics and document symbols;
- definition, references, and rename;
- hover, completion, and inlay hints;
- semantic tokens for the supported language subset (enable
editor.semanticHighlighting.enabled for Jadren if a selected theme has
suitable semantic-token colors);
- Windows native debugging through the local Microsoft C/C++ debug adapter.
The extension also contains an offline completion layer for core Jadren types,
keywords, and runtime helpers such as print and
time_now_unix_seconds. It does not require internet access or an API key. Type
fn, struct, if, for, module, import, print, or main and accept a
snippet with Tab. Press Ctrl+Space to show core completions manually.
While a file is being edited, the same offline layer also offers source-local
functions, parameters, let/var/const bindings, and declared types. These
fallback suggestions remain available during temporary syntax errors or while
the language server is starting; the LSP supplies the authoritative typed and
scope-aware results once the source is valid.
The fallback source index also understands local struct and enum members.
After a receiver and dot, such as point. or Status., completion offers the
declared fields or enum variants and replaces only the member prefix. Hovering
over a local function shows its signature, parameters and return type. While a
local call is being typed, ( and , open signature help for that function.
These local hints are intentionally conservative: they read only the current
file and never invent members for unknown or external types. For valid code,
the type-checked LSP remains authoritative.
UI syntax help
Windows UI built-ins are available without waiting for the language server.
Type part of a name such as ui_top, press Ctrl+Space, select the function,
and press Tab or Enter. The extension inserts the call with () and
placeholder arguments. For example, selecting ui_top_bar inserts:
ui_top_bar(height, background_color)
After writing (, VS Code opens signature help with the selected parameter,
its type and an explanation. Comma moves to the next parameter; use
Ctrl+Shift+Space to reopen the same help manually. Hovering over a ui_*
name shows the full syntax, return type and practical API note.
The first catalog covers the complete Windows Desktop Preview API: window,
top bar, text/panels/layout, buttons/events/state, forms/lists/scroll, native
menus, tooltips, themes and PNG/SVG assets. It is intentionally local/offline,
so it remains useful even when the source has an unfinished call or the LSP is
still starting. The repository smoke test compares this catalog with every
registered ui_* builtin, so a new UI API cannot be added without its editor
help being updated too.
The same offline signature catalog includes the general app_state_* store:
typed scalar/text keys, bounded UTF-8 read-back and flat-JSON save/load. The
help shows the caller-owned buffer required by app_state_read_text and the
documented 32-key/64-byte-key/256-byte-text limits.
app_state_count, app_state_exists, app_state_remove, and
app_state_read_key add bounded key enumeration and removal without requiring
every setting name to be hard-coded. app_state_exists distinguishes a missing
key from a stored zero, false, or empty string.
app_state_save_atomic combines temporary JSON output with the existing atomic
file replacement contract for crash-safe settings updates.
The catalog also documents the bounded app_list_* collection API, including
the list ID/index arguments, the writable buffer for app_list_read_text, and
transactional JSON persistence through app_list_save/app_list_load.
app_list_save_atomic adds the same temporary-path plus atomic-replace
contract for crash-resistant list settings.
The same catalog now includes app_table_* for four bounded application
tables: append/remove rows, set/read UTF-8 cells, and read the row count. Each
table has 64 rows, 8 columns and 256-byte cells; this model is independent from
the Windows ui_table widget. app_table_save/app_table_load persist the
full table as a nested JSON array with transactional restore. The catalog also
documents stable byte-wise app_table_sort_text and exact-match
app_table_find_text, including the descending flag and -1 not-found result.
app_table_filter_text copies exact matches into a separate destination table
while preserving source order; signature help calls out the source/destination
IDs and the rule that they must differ.
app_table_filter_text_ex extends this with explicit modes for exact,
contains, prefix, suffix, and ASCII case-insensitive matching (0..7).
app_table_save_atomic provides crash-resistant table persistence with the
same caller-owned temporary and target paths.
For input binding, ui_state_bind_text synchronizes a bounded text slot with
ui_text_input; ui_state_text_read and ui_state_text_set provide explicit
UTF-8 read-back and programmatic updates.
ui_list_bind_app and ui_table_bind_app connect native controls to bounded
application collections; call the matching *_refresh_app function after a
model mutation to update the control explicitly.
ui_input_bind_app_state connects a text input to an app_state text key;
native edits are stored automatically and ui_input_refresh_app_state reloads
the key after persistence has been loaded.
http_query_param extracts one exact query key from a target or query slice,
percent-decodes %HH and + into caller-owned output, and rejects malformed or
duplicate parameters.
app_state_tx_begin, app_state_tx_commit, and app_state_tx_rollback provide
a bounded in-memory snapshot for confirm/cancel form changes; they do not
replace durable file persistence or database transactions.
app_table_set_column_type, app_table_column_type, and
app_table_validate add process-local text/int/uint/bool column metadata and
validate non-empty cell values while keeping the existing JSON row format.
Filtered destination tables inherit the source schema, and loading validates
rows against the schema already configured by the caller.
app_table_save_schema/app_table_load_schema persist those eight column kinds
as a separate bounded JSON array, with the atomic save variant available for
crash-safe replacement.
Typed scalar reads are available through app_table_read_int,
app_table_read_uint, and app_table_read_bool; they require the matching
column kind and return bounded defaults for invalid or empty cells.
Typed scalar writes are available through app_table_set_int,
app_table_set_uint, and app_table_set_bool; the runtime formats the value
and validates it against the selected column kind.
app_table_tx_begin, app_table_tx_commit, and app_table_tx_rollback provide
a bounded process-local snapshot for grouped table edits; rollback restores the
rows and schema together.
Named typed-record metadata is available through app_table_set_column_name,
app_table_read_column_name, and app_table_find_column. Names are unique
ASCII identifiers and filtering/rollback preserve them. The full schema APIs
app_table_save_schema_full, app_table_save_schema_full_atomic, and
app_table_load_schema_full persist {name, kind} entries; the older
kind-only schema JSON remains compatible.
The named-field helpers app_table_set_named_cell/app_table_read_named_cell
and typed app_table_set_named_int/uint/bool plus read variants let source code
address a row by stable field name without manually resolving a column index.
For coordinated form updates, app_table_tx_begin_all,
app_table_tx_commit_all, and app_table_tx_rollback_all snapshot all four
bounded tables atomically; the existing single-table transaction remains
available and the two modes cannot be nested.
Full-schema metadata also has the bounded version helpers
app_table_schema_version/app_table_set_schema_version; saves include a
top-level version, old unversioned full schemas load as version 0, and
app_table_load_schema_full_if_version provides an atomic expected-version
guard for caller-managed migrations.
The model-wide app_data_tx_begin/app_data_tx_commit/
app_data_tx_rollback helpers snapshot app state, all bounded lists, and all
bounded tables together for a single confirm/cancel boundary.
The matching app_data_save, app_data_save_atomic, and app_data_load
helpers persist and restore that complete bounded model as one deterministic
length-framed checkpoint; the load is all-or-nothing and capped at 4 MiB.
For native HTTP clients, http_request_write builds a bounded request with
Host, Content-Length, and Connection: close; it performs no socket or TLS I/O.
The time_now_unix_seconds() -> Int64 helper returns the current UTC Unix
timestamp directly from the native runtime, with one-second precision.
time_now_monotonic_ms() -> UInt64 is the separate duration source; it is not
a calendar timestamp and is safe to compare across a TimeTracker interval.
The first allocation-free String helpers are string_length(String) and
string_equals(String, String); they operate on exact UTF-8 bytes and return
the length in bytes or an equality flag.
string_builder_append and string_builder_append_bytes extend this with a
caller-owned bounded byte buffer and an explicit append offset; they do not
allocate or partially write on insufficient capacity.
Hex color literals such as 0x168EF5u32 have an inline VS Code color swatch.
Click the swatch to edit the color; the presentation is written back as a
0xRRGGBBu32 literal. ui_theme_color(role) reads the current semantic theme
color and is intentionally a getter. Use the returned value in a control, for
example let primary: UInt32 = ui_theme_color(3), or use a literal when a
custom color is required. Roles are 0 window, 1 top bar, 2 panel,
3 primary, 4 safe, 5 status, 6 text and 7 secondary text.
ui_icon_button accepts stable system icon names such as search, settings,
help, download, save, close, menu and refresh; unknown values remain
ordinary text or Unicode labels.
Extension updates
The extension supports both update channels:
- Marketplace installation uses VS Code's native Auto Update service. The
extension is prepared for the
jadren publisher and the public Jadren
repository; each Marketplace release must use a higher extension version.
- A local
.vsix installation can use Jadren: Check for Extension Updates
or the background self-hosted check. The default catalog is
https://jadren.rhsoft.eu/api/releases and can be changed with
jadren.updates.server.
The self-hosted path accepts only HTTPS, keeps the artifact on the configured
host, enforces the catalog's VSIX size, verifies the published byte count and
SHA-256, and asks before installing. Set jadren.updates.enabled to false
to disable background checks; the explicit command remains available.
Hovering over a supported keyword or core type shows a short offline tooltip.
The LSP still provides richer symbol-specific hover information when available.
Jadren Debugger 0.2 (Windows)
Open a saved .jdn file and press F5, or run Jadren: Debug Current File.
F5 is bound both when the .jdn editor has focus and when the Explorer or
another VS Code side panel has focus; while an active debug session is running,
it keeps VS Code's normal continue behaviour.
The same command appears in the editor title's Run menu and in the Explorer
context menu for .jdn files. The top-level Run > Start Debugging command
remains the configuration-based VS Code debugger command.
Jadren: Build Release EXE appears beside it in both menus. It runs
jadren build --profile release without starting a debugger and writes
target/jadren/release/<source-name>.exe by default; configure
jadren.build.releaseOutputDirectory for a different directory.
The extension builds a debug executable and its adjacent .pdb file, then
launches the local cppvsdbg Debug Adapter Protocol implementation supplied by
the Microsoft C/C++ extension (ms-vscode.cpptools). The dependency is
declared by this extension and must remain installed.
The generated CodeView/PDB already exposes the native call stack and named
source let locals. With jadren.debug.stopAtEntry enabled, the current
preview pauses at jadren_entry() and the Variables panel shows answer.
Continue and step controls use the same native debug session. Source-line
breakpoints use the Jadren-owned Jadren: Toggle Source Breakpoint command
(F9 while the .jdn editor has focus), which registers a VS Code
SourceBreakpoint against the active Jadren line before launch. The verified
fixture stops at debugger-smoke.jdn:4 in main() and keeps answer visible
in Variables. The default output is
target/jadren/debug/<source-name>.exe; change
jadren.debug.outputDirectory when a workspace needs a different location.
For an interactive Variables or call-stack check, set
jadren.debug.stopAtEntry to true; the default remains false for normal
F5 runs.
The preview also allows path-based binding when the LLVM PDB has no source
checksum; the generated line table and source path are still validated by the
Jadren debugger smoke check.
Debugger 0.2 is a Windows developer-preview feature. It maps supported Jadren
source locations and named user locals to native code. Compiler-generated
temporaries, runtime panic inspection, expression evaluation, and pretty
printers remain later work.
Development checks
From the repository root:
pwsh -File scripts/check-vscode-extension.ps1
pwsh -File scripts/check-vscode-package.ps1
node scripts/check-vscode-offline-tools.js
Marketplace publication, VSIX signing, and release provenance are separate
release gates.