Use zerosyntax-lsp with any editor that supports the Language Server Protocol
over stdio.
- Download the Windows x64 or Linux x64 server archive from the latest release.
- Verify the archive against
SHA256SUMS.txtfrom the same release. - Extract the archive and put
zerosyntax-lsp(orzerosyntax-lsp.exe) on yourPATH, or configure its absolute path in your editor. - Register the server for the Generals/Zero Hour
.inifiles in your project.
The server writes protocol messages to stdout, so clients must launch it using stdio rather than a TCP port.
Use the check subcommand to run the same parser, schema, workspace index, and
diagnostics without an LSP client:
zerosyntax-lsp check Data/INI
zerosyntax-lsp check map.ini --base-root "C:/Games/Zero Hour"
zerosyntax-lsp check --fail-on warning Data/INI
zerosyntax-lsp check --json --stdin-filename map.ini - < generated.iniThe positional targets are .ini files, recursively scanned directories, or
one - for stdin. At least one target is required. All selected targets are
indexed together before diagnostics run, so references between them resolve.
Overlapping targets are checked once.
--base-root is repeatable and accepts directories or .big archives
containing base/mod INIs and game assets. Base roots participate in reference,
model, bone, audio, and texture checks but do not emit diagnostics themselves. For stdin,
--stdin-filename supplies the displayed/indexed name and enables map.ini or
solo.ini override semantics; it defaults to <stdin>.
Human output uses compiler-style records followed by a summary:
Data/INI/Weapon.ini:12:14: error[bad-number]: expected an integer, found `lots`
1 error(s), 0 warning(s), 0 hint(s)
--json writes a stable array to stdout. Each record has file, range,
severity, code, and message. Range lines and Unicode-scalar columns are
1-based; the end position is exclusive.
[{"file":"map.ini","range":{"start":{"line":2,"column":14},"end":{"line":2,"column":18}},"severity":"error","code":"bad-number","message":"expected an integer, found `lots`"}]Exit codes are:
0: no diagnostic meets the failure threshold.1: at least one diagnostic meets it.2: invalid arguments, inaccessible/unsupported inputs, or an internal failure.
The default threshold is error. Select --fail-on warning or
--fail-on hint for stricter CI. Diagnostics are still written to stdout when
the command exits 1; operational errors go to stderr.
Configure your LSP client with:
| Option | Value |
|---|---|
| Command | zerosyntax-lsp |
| Transport | stdio |
| Files | Zero Hour .ini files |
| Workspace root | Your map or mod directory |
The server indexes INI files under each workspace folder. Open the whole project to enable cross-file completion, definitions, references, rename, and workspace symbols.
{
"format": { "enable": false },
"preview": { "imageWidth": 160, "zoomPercent": 100 },
"schemaPath": "C:/Mods/MyMod/schema.json",
"analysis": {
"modelMemberStrictness": "compatible",
"allowPercentagesWithoutSign": false,
"mapOrderingDiagnostics": true,
"debounceMs": 250
},
"baseIniRoots": [
"C:/Games/Zero Hour",
"C:/Mods/MyMod/Data/INI",
"C:/Mods/MyMod.big"
]
}format.enablecontrols document formatting. It defaults tofalseand is dynamically registered when the client supports it.preview.imageWidthcontrols the displayed W3D thumbnail width in pixels (80–640, default160). The client still owns the outer details-pane bounds.preview.zoomPercentcontrols the default W3D camera zoom (25–400, default100). Both preview settings apply to newly resolved completions without restarting the server.schemaPathpoints to a custom schema JSON file. Unreadable or invalid files produce a warning and fall back to the built-in schema.analysis.modelMemberStrictnessisoff,compatible(member exists in any applicable model), orstrict(member exists in every applicable model). It defaults tocompatible.analysis.allowPercentagesWithoutSignaccepts engine-compatible bare numbers in percentage fields. It defaults tofalse, requiring the trailing%.analysis.mapOrderingDiagnosticscontrols source-backed forward-order warnings inmap.iniandsolo.ini. It defaults totrue.analysis.debounceMswaits this many milliseconds after the latest edit before refreshing whole-document indexes and diagnostics. Parsing and completions remain immediate. It defaults to250; valid values are0–5000, where0refreshes as soon as possible.baseIniRootsaccepts directories and.bigarchives containing base game or mod INI files and game assets. WAV/MP3 filenames and TGA/DDS textures power asset completion and warnings; DDS-only textures complete as the canonical INI spellingstem.tga. Audio and texture warnings activate independently only after that asset kind is indexed. Supply every loaded game/mod root to avoid warnings caused by a partial asset index. INI definitions are treated as loaded beforemap.iniandsolo.ini. Definitions in loose files open through nativefile:URIs. Definitions inside.bigarchives open as read-only virtual INIs with navigation and inspection support when the client selects thebigURI scheme.
The same settings can be sent at runtime through
workspace/didChangeConfiguration, either directly or nested under
{"zerosyntax": ...}. Analysis, debounce, and formatting changes apply
immediately. Schema and base-root changes rebuild the complete index, keep
filesystem scanning on a blocking worker, and report indexing progress.
Identical settings are ignored.
Clients without dynamic formatting registration keep their startup formatting capability. If such a client starts with formatting disabled, it must restart to expose formatting; all other settings still hot-reload. Only selecting a different server executable inherently requires a new process.
ZeroSyntax supports incremental document sync, diagnostics, completion, hover, go to definition, references, rename, semantic tokens, document and workspace symbols, folding ranges, quick fixes, and optional document formatting.
W3D model completion items support completionItem/resolve. Clients that render
Markdown completion documentation can show a lazy textured thumbnail
for the active Model = suggestion. The initial completion list contains no
image data. Previews use indexed loose or BIG-contained W3D/TGA/DDS assets and
cover mesh geometry, base materials, HLOD composition, and hierarchy bind pose.
preview.imageWidth changes its displayed size and preview.zoomPercent
changes the model framing.
Malformed or unsupported assets leave completion functional and show a short
preview-unavailable message. Rebuild the asset index or reload the server after
changing binary assets.
Install Rust 1.75 or newer, clone the repository, and run:
cargo build --locked --release -p zerosyntax-serverThe binary is written to target/release/zerosyntax-lsp (.exe on Windows).