Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>x2c - C with batteriesNew to Visual Studio Code? Get it now.
x2c - C with batteries

x2c - C with batteries

Preview

x2c

|
4 installs
| (0) | Free
x2c syntax highlighting and compiler language server support.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

x2c - C with batteries

This VS Code extension provides the TextMate grammar and language configuration for ordinary x2c source modules (.x, .xc, .xh, .x2c, and .xp) and Lisp files (.xlisp).

It highlights x2c list, array, map, string, Symbol, and SymbolSet literals, including data-first Array and Map contents and their runtime unquotes; pattern variables; runtime unquote and List splice forms; protocols; macros; decorators; with assignment blocks; alias declarations; List destructuring; imports; delegate fields; Self method types; standalone Lisp files; and the C-compatible syntax used by the language.

Macro signatures use $value for one syntax value and @items for a sequence. Code templates highlight @items, @producer(args), and quotation holes such as @(expression). Singular $ unquotes and $! source quotations use the macro sigil scope, including a standalone $. The color settings below make sigils bold. Quoted Lists retain runtime @items and @(expression) splices; Lisp retains ,@ unquote-splicing. Native C variadic ... remains distinct from macro syntax.

With a compatible x2c compiler available, the extension provides compiler diagnostics, definition navigation, type hover, completion, symbols, references, rename, and lexical semantic tokens. Syntax highlighting works without the compiler. The extension does not install tools or collect telemetry.

Installation

Run npm ci && npm run build in etc/vsc-extension, then install the resulting 0.4.0 VSIX with Extensions: Install from VSIX.

Compiler diagnostics, definitions, and hover

See the book's editor setup and configuration. Compiler language features require a compiler that provides x2c lsp and its matching server executable. Syntax highlighting remains available with older compilers; upgrade the compiler to enable language features.

For a development checkout, run make commands and select its matching compiler:

"x2c.semantic.compilerPath": "/path/to/x2c/builds/0/x2c"

VS Code 1.82 or newer is required. The extension starts x2c lsp over stdio and keeps one server per local workspace. Setup errors appear in the x2c Output channel.

Semantic analysis runs only in trusted local workspaces because compiling x2c can execute macros. Untrusted and virtual workspaces retain syntax highlighting. The book describes project/target selection, unsaved sources, native CPP limitations, and the boundaries of the server's results.

Distinct x2c colors

The extension contributes scopes but does not override the active theme. To use the colors shown below, copy either the dark or light setting into VS Code's settings.json.

Dark backgrounds:

"editor.tokenColorCustomizations": {
  "textMateRules": [
    {
      "scope": [
        "keyword.control.in.x2c",
        "keyword.control.try.x2c",
        "keyword.control.catch.x2c",
        "keyword.control.finally.x2c",
        "keyword.control.defer.x2c",
        "keyword.control.raise.x2c",
        "keyword.control.match.x2c",
        "storage.modifier.delegate.x2c",
        "storage.modifier.threaded.x2c",
        "storage.modifier.meta.x2c",
        "storage.modifier.native.x2c",
        "storage.modifier.module.x2c",
        "keyword.declaration.module.x2c",
        "keyword.control.import.x2c",
        "keyword.control.with.x2c",
        "keyword.declaration.alias.x2c",
        "keyword.declaration.protocol.x2c",
        "keyword.declaration.class.x2c",
        "keyword.control.foreach.x2c",
        "keyword.operator.is.x2c",
        "storage.type.self.x2c",
        "keyword.declaration.macro.x2c",
        "keyword.other.macro.using.x2c",
        "keyword.operator.arrow.x2c"
      ],
      "settings": { "foreground": "#FF4FD8", "fontStyle": "bold" }
    },
    {
      "scope": [
        "source.x2c punctuation.definition.literal",
        "source.x2c punctuation.definition.interpolation",
        "punctuation.definition.macro.sigil.x2c",
        "punctuation.definition.macro.splice.x2c"
      ],
      "settings": { "foreground": "#FF4FD8", "fontStyle": "bold" }
    },
    {
      "scope": "support.type.prelude.x2c",
      "settings": { "foreground": "#29D3E2", "fontStyle": "" }
    },
    {
      "scope": [
        "storage.type.macro.result.x2c",
        "storage.type.macro.hole.x2c"
      ],
      "settings": { "foreground": "#FFB454", "fontStyle": "italic" }
    }
  ]
}

Light backgrounds:

"editor.tokenColorCustomizations": {
  "textMateRules": [
    {
      "scope": [
        "keyword.control.in.x2c",
        "keyword.control.try.x2c",
        "keyword.control.catch.x2c",
        "keyword.control.finally.x2c",
        "keyword.control.defer.x2c",
        "keyword.control.raise.x2c",
        "keyword.control.match.x2c",
        "storage.modifier.delegate.x2c",
        "storage.modifier.threaded.x2c",
        "storage.modifier.meta.x2c",
        "storage.modifier.native.x2c",
        "storage.modifier.module.x2c",
        "keyword.declaration.module.x2c",
        "keyword.control.import.x2c",
        "keyword.control.with.x2c",
        "keyword.declaration.alias.x2c",
        "keyword.declaration.protocol.x2c",
        "keyword.declaration.class.x2c",
        "keyword.control.foreach.x2c",
        "keyword.operator.is.x2c",
        "storage.type.self.x2c",
        "keyword.declaration.macro.x2c",
        "keyword.other.macro.using.x2c",
        "keyword.operator.arrow.x2c"
      ],
      "settings": { "foreground": "#A626A4", "fontStyle": "bold" }
    },
    {
      "scope": [
        "source.x2c punctuation.definition.literal",
        "source.x2c punctuation.definition.interpolation",
        "punctuation.definition.macro.sigil.x2c",
        "punctuation.definition.macro.splice.x2c"
      ],
      "settings": { "foreground": "#A626A4", "fontStyle": "bold" }
    },
    {
      "scope": "support.type.prelude.x2c",
      "settings": { "foreground": "#007C8A", "fontStyle": "" }
    },
    {
      "scope": [
        "storage.type.macro.result.x2c",
        "storage.type.macro.hole.x2c"
      ],
      "settings": { "foreground": "#A15C00", "fontStyle": "italic" }
    }
  ]
}

Dark and light x2c highlighting

The syntax scopes cover in, try, catch, finally, defer, raise, match, delegate, threaded, import, with, alias, as, protocol, associated, foreach, is not, Self, macro, keyword, using, and =>. Prelude types use support.type.prelude.x2c: Array, Atom, Block, Buffer, Bytes, Context, Error, ErrorHandler, File, Func, Iter, Lambda, Lisp, List, Logger, LogSink, Map, Mutex, Pool, Scope, Split, String, Symbol, SymbolSet, Thread, Token, Tokenizer, and Var. Semantic macro types and capitalized syntax kinds share this type color; the complete catalog is below. Macro result and hole kinds keep the storage.type.macro.result.x2c and storage.type.macro.hole.x2c scopes.

For another background, keep the scope arrays and change only the foreground values. An empty fontStyle keeps prelude types upright. The specific keyword and modifier scopes retain their broader parent scopes, so existing theme rules continue to apply when these settings are absent.

Semantic macro types and syntax kinds

etc/syntax/grammar.x is the machine-readable source grammar. Its result-kind, hole-kind, and quotation-kind rules describe the syntax kinds; src/macros/macros.x owns their case-insensitive recognition. lib/meta.x declares the semantic macro types.

Category Names
Semantic macro types Code, Macro, Type, TypeInfo, Source
Result kinds Expr, Expression, Stmt, Field, Entry, Enumerator, Unit, Declaration, Decorator
Hole kinds Expr, Expression, Stmt, Field, Entry, Enumerator, Unit, Function, NamedType, Type, Decl, DeclaratorRow, Name, Literal, Param, Catch, Captures, MatchRow
Additional quotation kinds Type, Param

Stmt replaced Statement. Name and the other syntax kinds are grammar categories, not additional runtime typedefs. Outside result and hole positions, capitalized and uppercase kinds (such as Stmt and STMT) use support.type.prelude.x2c, like the reserved runtime types. Result and hole positions retain their existing specific scopes and italic type color.

Declarations use meta, meta static, meta native, or meta native static. The meta and native tokens have distinct modifier scopes and standard keyword scopes, so ordinary themes color them without custom settings. Declarations can follow another declaration on the same line or continue across comments and line breaks. A static macro uses the ordinary static modifier and the macro declaration scope. Named, local, and anonymous macro definitions share the macro declaration scope.

module before a declaration uses storage.modifier.x2c and storage.modifier.module.x2c. This includes macros, functions, typedefs, classes, and aggregate types. A module { ... } member block uses keyword.declaration.module.x2c. Private static type declarations keep the ordinary static modifier scope.

auto uses storage.modifier.auto.x2c for both managed declarations (including inferred types) and acquired-value initializers after =. Declaration auto cleans up the variable at block exit; initializer auto manages the acquired value like $auto(...). Macro using clauses recognize both retained names and fresh $name entries.

Managed compound declarations use one leading auto when cleanup semantics are unchanged: auto Array left = [], right = [];. Initializer auto remains available for bindings that change or mixed ownership groups. The grammar also highlights native auto regions, control statements, and function definitions, with auto (destination) for an explicit Scope. Empty auto() is rejected by the compiler, not the TextMate highlighter.

$!, $name, $(expression), and a standalone $ use pronounced sigil styling with the settings above. @ sequence forms share that styling. The grammar supplies scopes; the active VS Code theme controls their color and weight. Applying the recommended settings is necessary to guarantee bold sigils with a theme that does not style these scopes.

The website and mdBook read this TextMate grammar through site/shiki-x2c.mjs. Their dark and light palettes in site/shiki-x2c-theme.mjs use the same modifier colors and bold sigil settings. Both documentation and website examples therefore share these grammar scopes and styles.

Development

Open this directory in VS Code and press F5 to launch an Extension Development Host. Open an x2c source file and use Developer: Inspect Editor Tokens and Scopes to inspect the grammar.

The most useful scopes are:

  • punctuation.definition.literal.*.x2c for literal delimiters;
  • meta.literal.*.content.x2c for collection contents;
  • constant.other.atom.x2c for bare data names;
  • constant.other.symbol.x2c for symbols;
  • variable.other.pattern.*.x2c for pattern variables; and
  • variable.other.interpolation.*.x2c for runtime unquote and splice forms;
  • meta.destructuring.*.x2c and variable.other.readwrite.destructuring.x2c for List destructuring;
  • keyword.declaration.macro.x2c and entity.name.function.macro.x2c for macro definitions and applications;
  • punctuation.definition.macro.splice.x2c for sequence prefixes in code; and
  • *.lisp.x2c for standalone Lisp files.

Standard C strings retain the standard string.quoted.double and string.quoted.single scopes for theme compatibility.

Packaging

Install the pinned development dependencies, run the scope tests, then build the VSIX:

npm ci
npm test
npm run build

The packaged VSIX is tracked with the extension source. Install it from VS Code with Extensions: Install from VSIX.

When changing the grammar, keep x2c-specific rules ahead of competing C operator, call, string, and angle-bracket rules. Add scope tests for both the x2c form and the ordinary C syntax it could be confused with.

Marketplace identity

The Marketplace publisher is x2c-lang, displayed as x2c. The extension ID is x2c-lang.x2c-syntax. Version 0.4.0 retains the Preview label.

License and support

The extension is licensed under the Apache License 2.0; its attribution notice is in NOTICE. x2c is experimental and has no support commitment. See SUPPORT.md for reporting bugs and getting help.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft