Skip to content
| Marketplace
Sign in
Visual Studio>Tools>GUITKX
GUITKX

GUITKX

Yaniv Kalfa

|
34 installs
| (0) | Free
Syntax highlighting and language intelligence for .guitkx markup (ReactiveUI for Godot). Markup completion/hover; embedded GDScript is analyzed headlessly via gdscript-analyzer (no running Godot edito
Download

GUITKX — ReactiveUI for Godot

Editor support for .guitkx, the JSX-like markup of ReactiveUI for Godot — a React-style reactive UI library for Godot 4.x.

Features

  • Syntax highlighting for the JSX-like markup and the embedded GDScript, via a self-contained TextMate grammar.
  • Markup IntelliSense — completion and hover for host-element tags, structural/common attributes, control-flow directives (@if/@elif/@else/@for/@while/@match/@case/@default), and per-element event handlers.
  • Embedded-GDScript IntelliSense — completion, hover, and go-to-definition inside {expr}, setup, and control-flow conditions, analyzed in-process by the headless @gdscript-analyzer/core so you get real V.* / Hooks.* / Godot-API intelligence — no running Godot editor required, fully offline.
  • Diagnostics for structural problems.

Requirements

  • Node.js on your PATH (the bundled language server runs on Node).
  • That's it — embedded-GDScript intelligence runs offline; no Godot editor, no TCP/language-server connection.

Changelog

[0.9.0] - 2026-07-11

  • 0.9.0 naming loyalty (BREAKING, rides the library 0.9.0 — see MIGRATION-0.9.md): the language vocabulary is now 1:1 the official Godot names. Tags = class names (shorthands like VBox/Panel removed; ANY instantiable ClassDB Node class is now a valid tag, validated against the bundled dump); factories = V.ClassName verbatim; events = on + PascalCase(signal) derived for EVERY signal from ClassDB (the React alias table is gone — completions, hover, signature help and semantic tokens all speak onPressed/onValueChanged); style-key completion = the exact Godot property/theme/StyleBoxFlat names. Removed pre-0.9 tags get a precise "renamed in 0.9.0: use " diagnostic instead of a generic did-you-mean.

[0.8.8] - 2026-07-10

  • Picks up the runtime compiler's markup brace-matching fix (see its CHANGELOG.md for full detail): a parenthetical comment split across two #/## lines inside a component/directive body's setup code no longer desyncs delimiter matching -- previously it surfaced as a bogus GUITKX0304 "unclosed component body" anchored at the component's own {, far from the offending comment, in both editors' live diagnostics. Body content mode is now tracked per delimiter-stack level with per-line classification: setup statements (and their # comments) scan as GDScript, markup-shaped lines and return ( ... ) windows keep markup lexis (a literal # in element text stays literal). The same fix covers keyword bait ("# early return (see docs") and # comments inside multi-line array literals. Also faster markup parsing on large files: the parser's per-element line lookup is now a binary search over a prebuilt line-start table instead of an O(n) scan per element -- this runs on every keystroke.

[0.8.7] - 2026-07-06

  • Picks up a batch of compiler/formatter correctness fixes from the runtime addon (see its CHANGELOG.md for the full detail): markup-lexis brace/paren matching, so a literal # in element text (e.g. "Score #3") or a markup comment (////* *//<!-- -->) containing }/) can no longer miscount the delimiters the compiler uses to find a component/directive body or a return ( ... ) window -- previously a silent miscompile risk, not just a parse error. The formatter no longer re-indents or collapses spaces inside a triple-quoted string's interior, and no longer drops interior blank lines when re-anchoring a directive body's prep code. A handful of smaller hardenings: a truncated closing tag at the very end of a window now fails cleanly instead of scanning past it; format() now reports when it fell back to verbatim (a syntax error) instead of looking identical to "nothing to format" -- surfaced as a one-time warning per file in both editors.
  • The embedded-GDScript reflow safety net (BUG-1) now treats comments as part of the token stream it compares before and after reflowing -- a gdscript-fmt bug that deleted or mangled a comment used to normalize identically to the original (both "nothing"), so the guard called it safe and applied the reflow anyway, silently deleting the comment. A dropped or mangled comment is now rejected exactly like any other structural change; trailing whitespace inside a comment still doesn't count.
  • guitkx.* settings (enableEmbeddedAnalysis, useGdformat, enableGdscriptAnalysis) now apply live: the language server re-reads them on a workspace/didChangeConfiguration notification instead of only once at startup, so a toggle no longer needs a server restart to take effect. enableGdscriptAnalysis is also now enforced server-side across every request handler (VS2022 previously had no way to actually turn off plain-.gd analysis at all -- the option was persisted but silently unenforced; VS Code already gated it client-side by not registering the .gd document selector).
  • A closed file's diagnostics no longer linger in the Problems panel until it's reopened. .guitkx typing defaults (both editors) now match the formatter's canonical spaces-at-2 style -- previously tabs/4, which meant every hand-typed line got rewritten by the next format-on-save. The shipped package no longer bundles the language server's compiled test code (pure size, never needed at runtime).
  • Format-on-save no longer risks hanging Visual Studio: the request now times out after 2 seconds instead of blocking the UI thread indefinitely when the server is slow to respond (e.g. mid workspace scan). "Analyze plain .gd files" is now actually enforced (previously a persisted-but-ignored setting). guitkx.* option changes in Tools > Options > GUITKX now push to the running language server immediately, with no restart needed. "Restart Language Server" now warns when Visual Studio's one-time-per-session auto-restart budget is already spent instead of promising a restart that won't happen, and the server's stderr is now captured in a new "GUITKX Language Server" Output pane so a hang or crash is diagnosable without attaching a debugger.

[0.8.6] - 2026-07-06

  • Repackaged onto the shared language server, jumping straight from 0.5.5 to 0.8.6 -- inheriting every VS Code release in between in one shot: camelCase hooks tooling (completion/hover/go-to-def all speak useState/useEffect/... now, 23 hooks), diagnostic codes renumbered onto the Unity-shared table, gdscript-analyzer 0.6.0 (Godot's own verbatim error messages, wrong-arity call errors, unreachable-code dimming), early/conditional markup returns with full live intelligence, the directive-bodies-are-code-blocks grammar (prep GDScript + return ( <markup> ), GUITKX2103/2104), format-on-save enabled by default at the spaces-2 canonical style, the compiler-sidecar watch (post-save compiler-only errors now reach the editor), and live dangling-reference/duplicate-class detection (GUITKX2106/2107) including folder-delete handling. See ide-extensions/vscode/CHANGELOG.md for the full per-release detail this jump absorbs.

[0.5.5] - 2026-07-02

  • Bundles gdscript-analyzer 0.5.4: a typo'd method on a built-in value — sliced[1].casll(1) on a useState pair, s.upper() on a String (a Godot-3 rename), v.zzz on a Vector2 — is now an error with a precise squiggle, exactly where Godot itself errors. Works through plain untyped var s = useState(0) locals (the analyzer narrows single-assignment locals to their initializer's type), and Dictionary d.key sugar now types as the value and can never false-flag.

[0.5.4] - 2026-07-02

  • A typo'd hook call (usseState(0)) is now flagged live as an error, mapped onto the typo. The bundled analyzer (0.5.3) proves a name is defined nowhere only when it holds the whole project: the server feeds every .gd at startup, keeps the view current through a file watcher (created/edited/deleted files and folders, plus project.godot autoload changes), and re-checks open files once armed. Names declared only in a sibling .guitkx (whose generated .gd isn't on disk yet) are never false-flagged.
  • GUITKX0108 (a @for/@while body with more than one root element) and GUITKX0102 (a component with no return ( ... )) now fire live while typing, precisely ranged — previously they appeared only after a save, pinned to line 1 via the compiler sidecar.
  • useState/useReducer/useTransition returns are now typed pairs end-to-end: s := useState(0) makes s[1] a checkable Callable (hover, inlay hints, and future setter-typo checking), via ## @return-tuple(...) tags in hooks.gd and real wrapper-func hook stubs in the virtual document. Hook declarations also keep their parameters and -> Hint in the analysis view, so hovering or navigating a hook parameter works.
  • Fixed a formatter/compiler regression family around indentation anchoring: one outlier-shallow setup line, or an over-indented leading comment, no longer shifts the rest of the block (which produced an invalid generated .gd and could dedent an if body during Format Document). Module members are analyzed under their real names, so a sibling component's bare call to a module-local hook resolves.

[0.5.3] - 2026-07-02

  • Formatting a .guitkx file now normalizes embedded GDScript indentation to real tabs by depth. A nested setup line — most visibly a lambda body — could previously come out as a tab followed by spaces (\t ), which renders like two tabs but is a byte-level tab/space mix; the formatter now re-indents it to clean tabs, matching the compiler's _reindent_setup. Applies to component setup and hook bodies.
  • A misspelled declaration keyword no longer blacks out the rest of the file. The language server now recovers a near-miss component/hook/module header (e.g. comssponent Foo {) for analysis, so markup diagnostics, embedded-GDScript checks, tag highlighting, and completion keep working while you fix the typo — instead of every other error silently vanishing. Markup diagnostics are also resilient to a malformed tag now: one bad < a> no longer collapses the whole component's markup window. And a misspelled @class_name directive (e.g. @clasaas_name) is flagged as GUITKX0300 with a did-you-mean, instead of being silently ignored.

[0.5.2] - 2026-07-02

  • A misspelled declaration keyword (e.g. comssponent instead of component) or an invalid @class_name value is now reported live — GUITKX0102 / GUITKX0300 — instead of silently blacking out the whole file. Previously the editor skipped ALL analysis whenever it could not find a valid component/hook/module header, so one typo in the header made every other error (and hover/completion) vanish with no indication why. A < followed by whitespace inside markup is also flagged live now as an invalid tag name.

[0.5.1] - 2026-07-02

  • .guitkx files that mix tabs and spaces in a component's setup — a tab followed by spaces renders identically to tabs, so the difference is invisible in the editor — no longer trigger a spurious Mixed use of tabs and spaces / expected a declaration error cascade. The embedded-GDScript virtual document now normalizes setup indentation by depth (a tab and the inferred space-unit each count as one level), matching the compiler.

[0.5.0] - 2026-07-01

  • Hooks are now camelCase (React parity): completion, hover, go-to-definition, and the embedded-GDScript virtual document all use the camelCase names — useState, useEffect, useRef, useMemo, useContext, createContext, … (23 hooks). Existing snake_case hook code must be migrated (a snake→camel rename over the 23 hook names).
  • Hovering a hook now shows its signature — e.g. useState(initial) → [value, setter] — instead of a bare Callable. Host-element hover drops the internal V.* factory detail and keeps the Godot class reference.
  • Unreachable code after a component's return (...) is now dimmed (faded) live, the same way dead code is shown for GDScript — via an Unnecessary-tagged diagnostic.
  • Duplicate-key detection now covers expression keys (key={ str(i) }), not only literal key="x" — two siblings sharing the same key expression collide on every iteration.
  • The markup parser now reports a < followed by whitespace (e.g. < a>) as an invalid tag name, instead of silently treating it as a fragment plus an attribute.

[0.4.0] - 2026-07-01

  • Event handlers in .guitkx now use React-style camelCase names — onClick, onChange, onSubmit, onFocus, onBlur, onPointerDown/onPointerUp/onPointerEnter/onPointerLeave, onResize — and the editor understands them everywhere: completion offers the right events per control, hover shows the underlying Godot signal and its argument signature, signature help fires inside the handler, unknown-attribute validation accepts them, and they are semantically highlighted as events. onChange is polymorphic — it is offered for (and binds to) whichever value/selection signal the control actually exposes (text_changed, value_changed, item_selected, tab_changed, or toggled). The native on_<signal> spelling is still recognized as an escape hatch to any Godot signal.
  • Prop spread {...obj} is now recognized in markup: it is highlighted, never flagged as an unknown attribute, and preserved (and kept idempotent) by the formatter — matching the compiler, which merges a spread with explicit props left-to-right (later wins), on both host elements and components.

[0.3.1] - 2026-07-01

  • Hover, completion, and go-to-definition now work for embedded GDScript in a component's setup block (the lines before return (...)). They were returning nothing — including hooks like use_state — because the setup region's source map was dropped on CRLF files or when the block ended in a blank line; it is now mapped line by line.
  • Hover in markup now resolves the full identifier under the cursor against host elements, your own components, and the host element's ClassDB properties and signals. Previously it only matched a host tag at the exact end of its name, so attributes (text, separation, on_pressed, …) and component tags hovered to nothing. A component tag's hover also shows its parameter signature.
  • Completion now fires at a blank markup position — an empty child slot or inside an @for/@if body — and offers your project's components as <Tag> suggestions. Those positions were being misread as embedded GDScript, so nothing was offered.
  • Go-to-definition, find-references, and rename now work from a component's <Tag> usage (including with the cursor on the opening <), from the component declaration name, AND from its @class_name directive — previously F12 / ctrl+click on the declaration or the @class_name reported 'no definition found' and find-references came up empty. A GDScript comparison such as a < Name is never mistaken for a tag.
  • Renaming a component that declares @class_name now rewrites the @class_name directive, the declaration, and every <Tag> usage together. It previously left @class_name stale, so the renamed usages reported a dangling GUITKX0105 'unknown element' error.
  • Embedded GDScript inside .guitkx is now semantically highlighted by the analyzer (type-aware), the same way a real .gd file is, instead of grammar-only colouring.
  • Embedded GDScript inside .guitkx is now formatted by the bundled analyzer — the same gdscript-fmt that formats plain .gd files — so a snippet formats identically in a .gd and in .guitkx. The optional external gdformat dependency is gone.

[0.3.0] - 2026-06-30

  • The extension now drives plain .gd files through gdscript-analyzer, not just .guitkx markup: diagnostics, completion, hover, go-to-definition, project-wide find-references and rename, signature help, inlay hints, code actions, document symbols, formatting, and semantic highlighting, all headless with no running Godot editor. It is ON by default; the new guitkx.enableGdscriptAnalysis setting turns it off. Because it runs alongside the godot-tools extension, disable godot-tools' language server to avoid duplicate diagnostics on .gd files.
  • Embedded GDScript inside .guitkx now also gets find-references, project-wide rename (correct-or-refuse), signature help, inlay hints, and code actions, on top of the existing completion, hover, diagnostics, and go-to-definition.
  • Upgraded the bundled GDScript analyzer to 0.5.2, which exposes GDScript formatting and semantic highlighting, now wired for .gd via Format Document and semantic tokens.

[0.2.6] - 2026-06-28

  • Go-to-definition now resolves across files fully offline (no running Godot editor): a library symbol such as a hook's use_ref now jumps to its real implementation in core/hooks.gd, landing on the declaration in that file. Previously only same-file symbols resolved headlessly; cross-file navigation required a running Godot editor.
  • Upgraded the bundled GDScript analyzer to 0.4.0: navigation and diagnostics now cross the extension boundary as native objects, and each navigation target reports its file directly, making cross-file go-to-definition faster and more robust.

[0.2.5] - 2026-06-27

  • Embedded-GDScript intelligence (completion, hover, and go-to-definition inside {expr}/setup blocks) is now analyzed in-process by gdscript-analyzer, with no running Godot editor or TCP connection required, so it works fully offline. Go-to-definition now resolves same-file symbols (the previous Godot-proxy path could not). The guitkx.enableGodotProxy and guitkx.godotLanguageServerPort settings are replaced by a single guitkx.enableEmbeddedAnalysis toggle (the legacy enableGodotProxy value is still honored for back-compat).
  • Embedded-GDScript type and parse diagnostics (e.g. integer division, type mismatch, syntax errors) now surface as squiggles inside {expr}/setup blocks, mapped back into the .guitkx source. Unresolved library/cross-file symbols never warn (the analyzer treats them as the Unknown seam), so this adds real diagnostics with no false positives.

[0.2.4] - 2026-06-22

  • Formatting: an authored blank line at the start or end of a component/hook setup block is now preserved (it was being stripped), and runs of 2+ spaces in embedded GDScript are collapsed to one outside strings/comments (e.g. if x == null becomes if x == null).
  • Diagnostics: an unknown element (GUITKX0105) and an unknown host attribute (GUITKX0107) are now reported as Errors (a red squiggle) instead of a faint hint / a warning.
  • Completion: style-dict keys (bg_color, corner_radius, pad, separation, expand_h, font_size, the theme channels, the per-state slots, …) are offered inside a style={ {…} } (or *_style) dictionary; common built-in constants (Color.WHITE, Vector2.ZERO, …) complete after Type.; and go-to-definition on an embedded GDScript symbol now forwards to Godot's language server (jumping to the library .gd, e.g. use_ref → core/hooks.gd) when the editor is running.

[0.2.3] - 2026-06-22

  • Formatting now always uses tab indentation for .guitkx (the embedded GDScript requires tabs, and the compiler emits tabs), so the markup and the embedded setup no longer mix indentation units — previously, with an editor configured for spaces, a deeper setup line kept its authored tab and produced a "2 spaces + tab" indent. Diagnostics: unknown attributes on a host element are now flagged (e.g. a typo'd te / xt on <Label>) with a did-you-mean suggestion, validated against the bundled Godot ClassDB property + signal data; component tags (which take arbitrary props) are not flagged, and the check is skipped when the ClassDB dump is unavailable so it never false-flags.
  • Formatter configuration: a project guitkx.config.json (Prettier-style walk-up, the analogue of ReactiveUIToolKit's uitkx.config.json) now overrides the formatter — printWidth, indentStyle ("tab" | "space"), indentSize, singleAttributePerLine, insertSpaceBeforeSelfClose. Tab indentation is the default when no config is present.

[0.2.1] - 2026-06-22

  • Renamed the extension to just "GUITKX" (it was "GUITKX (ReactiveUI for Godot)", which truncated to "GUITKX (React..." in the editor UI) and added the Godot logo as the extension / marketplace icon.

[0.2.0] - 2026-06-22

  • Formatter: components whose render is guarded by an early return null (e.g. if not ready: return null before the real markup return) are now formatted instead of being left verbatim, and the multi-attribute wrap path honors the insertSpaceBeforeSelfClose option (it previously always inserted the space).
  • Language server: hover and completion inside a hook body now map to the correct embedded-GDScript offset (the body is no longer mis-mapped after re-indentation); a <>...</> fragment no longer raises a false GUITKX0104 duplicate-key warning across its siblings; and parameter completion is now noncode-aware, so a string default containing a comma or colon (e.g. label: String = "a, b") no longer drops the parameters declared after it.
  • find-references and rename now use the exact jsx-as-value keyword boundaries the compiler uses (return / else / and only), so they never edit a <Name that the compiler reads as a less-than comparison (e.g. after if, in, not, await, yield, or or).
  • Control-flow inside an embedded expression that cannot be lowered to an expression (@while / @match) now reports GUITKX0113 through the compiler-diagnostics sidecar; @if/@elif/@else and @for inside a {expression} or a lambda now compile correctly (inline ternary / .map).

[0.1.0] - 2026-06-21

  • Initial release. Syntax highlighting and language intelligence for .guitkx markup (ReactiveUI for Godot): a self-contained TextMate grammar that colors both the JSX-like markup and the embedded GDScript; markup completion and hover for host-element tags, structural/common attributes, control-flow directives (@if/@elif/@else/@for/@while/@match/@case/@default) and per-element event handlers, served from the bundled schema; and embedded-GDScript completion/hover forwarded to Godot's built-in GDScript language server (TCP, engine port 6005) through a synthetic virtual .gd document with a length-preserving source map. Structural diagnostics (unbalanced braces) ship today; the Godot proxy degrades gracefully when the editor is not running so the markup features always work.
  • Visual Studio 2022 extension registers the TextMate grammar via .pkgdef (VS does not colorize over LSP) and drives the same Node language server through an ILanguageClient. Requires Node.js on PATH.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft