diff options
| author | David Czihak <git@dcz.at> | 2026-05-08 03:12:09 +0200 |
|---|---|---|
| committer | David Czihak <git@dcz.at> | 2026-05-08 03:12:09 +0200 |
| commit | d0436c0121254380e24cf4c99a61472377195d65 (patch) | |
| tree | 3aaabad7c0d89a2d9802641d6b751409f76ca05e /MANUAL.md | |
| parent | b9d713336bd4fdc5e40899257b1fe7a356ca8dcf (diff) | |
Chore: Add user manual
The manual has been generated based on the current state of the extension source code. I intend to improve it in the future, but since the new task system has so many features, I want them documented somewhere.
Diffstat (limited to 'MANUAL.md')
| -rw-r--r-- | MANUAL.md | 656 |
1 files changed, 656 insertions, 0 deletions
diff --git a/MANUAL.md b/MANUAL.md new file mode 100644 index 0000000..27a555e --- /dev/null +++ b/MANUAL.md @@ -0,0 +1,656 @@ +# Zig for Nova — User Manual + +This manual covers the task system. For installation, language-server, and +debugging prerequisites see [README.md](README.md). + +--- + +## Table of Contents + +- [Overview](#overview) +- [Creating a task](#creating-a-task) +- [Common options](#common-options) + - [Working Directory](#working-directory) + - [Optimize](#optimize) + - [Target](#target) + - [User Options](#user-options) + - [Build Arguments](#build-arguments) + - [Program Arguments](#program-arguments) +- [Task templates](#task-templates) + - [Zig Package](#zig-package) + - [Zig Debug](#zig-debug) + - [Zig Test](#zig-test) + - [Zig Watch](#zig-watch) +- [Automatic tasks](#automatic-tasks) + - [Current Zig File](#current-zig-file) + - [Discovered build steps](#discovered-build-steps) +- [Recipes](#recipes) + - [Run a single executable](#recipe-run-executable) + - [Run with a custom step name](#recipe-custom-step) + - [Cross-compile to a different target](#recipe-cross-compile) + - [Pass custom -D flags](#recipe-d-flags) + - [Run specific tests](#recipe-tests) + - [Ziglings-style projects](#recipe-ziglings) + - [Debug a binary that isn't in zig-out/bin](#recipe-debug) +- [Clean action](#clean-action) +- [Inline issue reporting](#inline-issues) +- [Settings reference](#settings) + +--- + +<a id="overview"></a> +## Overview + +The extension integrates with `zig build` at three levels: + +| Kind | How it appears | Configurable | Persistent | +|---|---|---|---| +| **Task template** | Added by you in Project Settings | Yes — full config UI | Yes — saved in `.nova/` | +| **Current Zig File** | Always present automatically | No | No | +| **Discovered step** | One per step in `zig build --list-steps` | No | No | + +Task templates are the right tool when you need to control optimize mode, +target, test filters, or program arguments. Automatic tasks are zero-config +quick-launchers. + +--- + +<a id="creating-a-task"></a> +## Creating a task + +1. Open **Project Settings** (`⌘,` with a project open, or **Project → + Project Settings…**). +2. Select the **Tasks** tab. +3. Click **+** and choose a template from the Zig section. +4. Fill in the options and close the panel — Nova saves the task automatically. + +Each task exposes up to three action slots that map to Nova's toolbar buttons: + +| Slot | Toolbar button | What it does | +|---|---|---| +| **Build** | ⌘B | Compiles without running | +| **Run** | ▶ | Builds (if needed) and runs | +| **Clean** | Broom icon | Removes build artifacts | + +--- + +<a id="common-options"></a> +## Common options + +Several options appear in more than one template. They are documented once +here and referenced from each template section. + +<a id="working-directory"></a> +### Working Directory + +| Field | Default | +|---|---| +| Working Directory | Workspace root | + +The directory from which `zig build` is invoked. Relative paths in other +options are resolved against this directory. Leave blank to use the workspace +root. + +Change this for monorepos or sub-package layouts where `build.zig` lives +below the workspace root. + +<a id="optimize"></a> +### Optimize + +| Value | Flag emitted | When to use | +|---|---|---| +| **Project Default** | *(nothing)* | Let `build.zig` decide (most projects default to `Debug`) | +| **Debug** | `-Doptimize=Debug` | Development, debugging | +| **ReleaseSafe** | `-Doptimize=ReleaseSafe` | Production with safety checks | +| **ReleaseFast** | `-Doptimize=ReleaseFast` | Maximum performance | +| **ReleaseSmall** | `-Doptimize=ReleaseSmall` | Smallest binary size | + +The flag is inserted immediately after `zig build`: +``` +zig build -Doptimize=ReleaseFast … +``` + +<a id="target"></a> +### Target + +| Field | Default | +|---|---| +| Target | *(host)* | + +A Zig target triple such as `aarch64-macos`, `x86_64-linux-gnu`, or +`wasm32-wasi`. Passed as `-Dtarget=<value>`. Leave blank to compile for the +machine you are running on. + +``` +zig build -Dtarget=aarch64-macos … +``` + +See `zig targets` for the full list of supported triples. + +<a id="user-options"></a> +### User Options + +A list of custom `-D` flags defined by the project's `build.zig`. Each entry +can be either: + +- `key` — emits `-Dkey` (boolean `true`) +- `key=value` — emits `-Dkey=value` + +Example entries and the flags they produce: + +| Entry | Flag | +|---|---| +| `verbose` | `-Dverbose` | +| `n=42` | `-Dn=42` | +| `healed-path=patches/healed` | `-Dhealed-path=patches/healed` | + +Entries that do not match the pattern `[A-Za-z_][A-Za-z0-9_-]*(=.*)?` are +silently skipped with a warning in the Extension Console. + +<a id="build-arguments"></a> +### Build Arguments + +Free-form arguments appended after the `-D` flags but before the step name. +Use this for `zig build` flags that are not exposed as dedicated fields, such +as `--summary all`, `--verbose`, or `-j4`. + +``` +zig build [-Doptimize=…] [-Dtarget=…] [-D…] <Build Arguments> [step] … +``` + +<a id="program-arguments"></a> +### Program Arguments + +Arguments passed to the compiled program after `--`: + +``` +zig build … run -- <Program Arguments> +``` + +For the **Zig Debug** template these are forwarded to the debugger's launch +request instead. + +--- + +<a id="task-templates"></a> +## Task templates + +<a id="zig-package"></a> +### Zig Package + +> **Build → Run → Clean** a Zig package from a single task configuration. + +**When to use:** everyday development — building, running, and cleaning a +package whose output is an executable. + +#### Actions + +| Action | Command | +|---|---| +| Build | `zig build [flags…]` | +| Run | `zig build [flags…] [step] [-- program-args]` | +| Clean | removes `.zig-cache`, `zig-cache`, `zig-out` | + +The Build action compiles without running (equivalent to `zig build` with no +run step). The Run action builds *and* runs in a single `zig build` invocation +— Nova does not chain them; `zig build` handles both internally. + +#### Options + +| Option | Type | Default | Description | +|---|---|---|---| +| Working Directory | path | workspace root | See [Working Directory](#working-directory) | +| Run Step | string | *(blank)* | Step name for the Run action. See below. | +| Optimize | enum | Project Default | See [Optimize](#optimize) | +| Target | string | host | See [Target](#target) | +| User Options | string list | — | See [User Options](#user-options) | +| Build Arguments | string list | — | See [Build Arguments](#build-arguments) | +| Program Arguments | string list | — | See [Program Arguments](#program-arguments) | +| Console | enum | Internal Console | Where to run the program | + +#### Run Step + +The step name appended to `zig build` for the Run action. Common values: + +| Value | Command produced | When | +|---|---|---| +| *(blank)* | `zig build` | Default install step — artifacts land in `zig-out/` | +| `run` | `zig build run` | Project exposes a `run` step | +| `serve` | `zig build serve` | Any custom step name | + +Leave blank if the project uses `-D` flags instead of a step name (Ziglings +style — see [Recipes](#recipes)). + +#### Console + +| Value | Behaviour | +|---|---| +| **Internal Console** | Output appears in Nova's built-in console panel | +| **External Terminal** | Opens macOS Terminal.app in a new window or tab | + +Use External Terminal for interactive programs that read from stdin. + +--- + +<a id="zig-debug"></a> +### Zig Debug + +> **Build → Debug** a Zig executable under lldb-dap. + +**When to use:** stepping through code, setting breakpoints, inspecting +variables. + +The Run action always triggers a Build first (`buildBeforeRunning`), so the +debugger always launches the freshest binary. + +Requires `lldb-dap`, discovered automatically via `xcrun` or `PATH`. Install +the Xcode Command Line Tools if it is missing: `xcode-select --install`. + +#### Actions + +| Action | Command | +|---|---| +| Build | `zig build -Doptimize=<mode> [flags…]` | +| Run | launches lldb-dap (build runs first automatically) | +| Clean | removes `.zig-cache`, `zig-cache`, `zig-out` | + +#### Options + +| Option | Type | Default | Description | +|---|---|---|---| +| Working Directory | path | workspace root | See [Working Directory](#working-directory) | +| Program | path | *(auto-detected)* | Path to the executable to debug. See below. | +| Optimize | enum | **Debug** | See [Optimize](#optimize) | +| Target | string | host | See [Target](#target) | +| User Options | string list | — | See [User Options](#user-options) | +| Build Arguments | string list | — | See [Build Arguments](#build-arguments) | +| Program Arguments | string list | — | Forwarded to the debugged process | +| Console | enum | Internal Console | Where the debugged process runs | +| Stop On Entry | boolean | off | Pause at the very first instruction | + +#### Program path auto-detection + +When the **Program** field is blank, the extension reads `build.zig.zon` and +extracts the package `.name`. It then probes `zig-out/bin/<name>` relative to +the working directory. If the file exists it is used automatically; otherwise +the task shows a warning asking you to fill in the field manually. + +This works for the common case of a single executable whose name matches the +package name. For other layouts — multiple executables, custom install +prefixes, library packages — set the path explicitly. + +#### Console (debug) + +| Value | Where the debugged process runs | +|---|---| +| **Internal Console** | Nova's built-in console (default) | +| **Integrated Terminal** | Nova's integrated terminal | +| **External Terminal** | macOS Terminal.app | + +--- + +<a id="zig-test"></a> +### Zig Test + +> **Build → Run → Clean** tests via `zig build test`. + +**When to use:** running the project's test suite, optionally filtered to a +subset of tests. + +#### Actions + +| Action | Command | +|---|---| +| Build | `zig build test [flags…]` | +| Run | `zig build test [flags…] [--summary=…] [--test-filter …] [-- runner-args]` | +| Clean | removes `.zig-cache`, `zig-cache`, `zig-out` | + +Both Build and Run invoke `zig build test`. The distinction is that the Run +action additionally applies the Test Filter and Summary fields. + +Test failures surface as inline issues in the editor via the same +`file:line:col: error:` pattern used for compiler errors. + +#### Options + +| Option | Type | Default | Description | +|---|---|---|---| +| Working Directory | path | workspace root | See [Working Directory](#working-directory) | +| Test Filter | string | — | Substring filter on test names. See below. | +| Summary | enum | Default | Verbosity of `--summary`. See below. | +| Optimize | enum | Project Default | See [Optimize](#optimize) | +| Target | string | host | See [Target](#target) | +| User Options | string list | — | See [User Options](#user-options) | +| Build Arguments | string list | — | Appended after `zig build test` | +| Program Arguments | string list | — | Passed after `--` to the test runner | + +#### Test Filter + +A substring of the test name. Only tests whose names contain this string are +run. Maps directly to `zig build`'s `--test-filter` flag. + +``` +zig build test --test-filter "parser" +``` + +Leave blank to run all tests. + +#### Summary + +Controls how much output `zig build` prints about the test run. + +| Value | Flag | Output | +|---|---|---| +| **Default** | *(nothing)* | Zig's built-in default | +| **All** | `--summary=all` | Every step result | +| **Failures only** | `--summary=failures` | Only failed steps | +| **None** | `--summary=none` | Silent on success | + +--- + +<a id="zig-watch"></a> +### Zig Watch + +> **Build** with `zig build --watch`, rebuilding automatically on file changes. + +**When to use:** tight edit–compile loops where you want continuous feedback +without manually re-triggering the Build action. + +> **⚠ Known limitation:** Nova's issue matchers fire only on the first build +> cycle. Errors found in subsequent automatic rebuilds will not appear as +> inline annotations in the editor. Re-run the task (stop and start again) to +> refresh the issue overlay. + +#### Actions + +| Action | Command | +|---|---| +| Build | `zig build [step] --watch [--debounce N] [-fincremental] [flags…]` | +| Clean | removes `.zig-cache`, `zig-cache`, `zig-out` | + +There is no Run action — `zig build --watch` manages the build loop itself. + +#### Options + +| Option | Type | Default | Description | +|---|---|---|---| +| Working Directory | path | workspace root | See [Working Directory](#working-directory) | +| Step | string | *(blank)* | Step to watch. Leave blank for Zig's default install step. | +| Debounce (ms) | number | *(Zig default)* | Milliseconds to wait after a change before rebuilding. | +| Incremental | enum | Default | Force incremental compilation on or off. | +| Optimize | enum | Project Default | See [Optimize](#optimize) | +| Target | string | host | See [Target](#target) | +| User Options | string list | — | See [User Options](#user-options) | +| Build Arguments | string list | — | See [Build Arguments](#build-arguments) | + +#### Debounce + +Passed as `--debounce <N>` to `zig build`. Controls how long Zig waits after +detecting a file change before starting a rebuild. Useful on projects with +slow file-system events or many simultaneous saves. Leave blank to use Zig's +built-in default. + +#### Incremental + +| Value | Flag | Effect | +|---|---|---| +| **Default** | *(nothing)* | Zig decides | +| **On** | `-fincremental` | Force incremental compilation on | +| **Off** | `-fno-incremental` | Force incremental compilation off | + +--- + +<a id="automatic-tasks"></a> +## Automatic tasks + +Automatic tasks appear in the task list without any configuration. They cannot +be edited and are not saved in project settings. + +<a id="current-zig-file"></a> +### Current Zig File + +Always present. Targets whichever `.zig` file is currently focused in the +editor. + +| Action | Command | +|---|---| +| Run | `zig run <active-file>` (in the file's directory) | +| Clean | removes `.zig-cache`, `zig-cache`, `zig-out` from the nearest ancestor directory that contains a `build.zig` | + +The Clean action walks up the directory tree from the active file until it +finds a `build.zig`, then cleans that project root. If no `build.zig` is +found above the file, it falls back to the workspace root. + +**Note:** there is no Build action — `zig run` compiles and runs in one step. + +--- + +<a id="discovered-build-steps"></a> +### Discovered build steps + +When the workspace contains a `build.zig`, the extension runs +`zig build --list-steps` in the background and creates one task per step: + +``` +Zig Build: install +Zig Build: run +Zig Build: test +Zig Build: bench +… +``` + +Each task has a single **Run** action that invokes `zig build <step>` in the +workspace root with no extra flags. + +#### How discovery works + +1. On workspace open (or task-list refresh), the extension stats `build.zig` + and `build.zig.zon` to capture their modification times. +2. It spawns `zig build --list-steps` asynchronously — the workspace is usable + immediately; discovered tasks appear once the command finishes. +3. The result is cached. The cache is considered fresh if: + - Both `build.zig` and `build.zig.zon` have the same mtimes as when last + fetched, **and** + - The cache is less than 5 minutes old. +4. When `build.zig` or `build.zig.zon` changes on disk, the cache is + invalidated and `--list-steps` is re-run automatically. + +#### What steps appear + +`zig build --list-steps` executes `build.zig` with no `-D` options, so only +the steps registered unconditionally by the build script are visible. Steps +that are registered only under a `-D` branch (such as Ziglings' `zigling` and +`random` steps) do not appear unless that branch is taken — and it won't be, +because the discovery command passes no flags. + +Steps whose names are not valid identifiers (`[A-Za-z_][A-Za-z0-9_-]*`) are +silently filtered out. + +#### Disabling discovery + +Some projects run expensive logic at the top of `build()` that you may not +want triggered on every workspace open. Discovery can be turned off: + +- **Globally:** Nova Preferences → Extensions → Zig → Tasks → uncheck + **Discover Build Steps**. +- **Per workspace:** Project Settings → Zig → Tasks → uncheck **Discover Build + Steps** (overrides the global setting for this project only). + +When disabled, the `Zig Build: <step>` tasks disappear; the +[Current Zig File](#current-zig-file) task and all configured templates are +unaffected. + +--- + +<a id="recipes"></a> +## Recipes + +<a id="recipe-run-executable"></a> +### Run a single executable + +Create a **Zig Package** task. + +- **Run Step:** `run` (or the name your `build.zig` uses for the run step) +- Leave everything else at defaults. + +The Run (▶) button compiles and launches the program in Nova's console. + +<a id="recipe-custom-step"></a> +### Run with a custom step name + +Same as above but change **Run Step** to whatever `b.step(…)` name your +`build.zig` declares: + +```zig +const serve_step = b.step("serve", "Start the HTTP server"); +``` + +→ set **Run Step** to `serve`. + +<a id="recipe-cross-compile"></a> +### Cross-compile to a different target + +Create a **Zig Package** task and set: + +- **Target:** `aarch64-linux-musl` +- **Optimize:** `ReleaseSmall` + +The command produced will be: +``` +zig build -Doptimize=ReleaseSmall -Dtarget=aarch64-linux-musl run +``` + +<a id="recipe-d-flags"></a> +### Pass custom -D flags + +Your `build.zig` declares: + +```zig +const verbose = b.option(bool, "verbose", "Enable verbose output") orelse false; +const port = b.option(u16, "port", "Listening port") orelse 8080; +``` + +Add two entries to **User Options**: + +| Entry | Flag produced | +|---|---| +| `verbose` | `-Dverbose` | +| `port=9000` | `-Dport=9000` | + +<a id="recipe-tests"></a> +### Run specific tests + +Create a **Zig Test** task and set: + +- **Test Filter:** `parser` (runs any test whose name contains "parser") +- **Summary:** Failures only (quieter output when most tests pass) + +<a id="recipe-ziglings"></a> +### Ziglings-style projects + +Ziglings selects exercises with `-Dn=<number>` rather than a named step. + +For "run all exercises" use a **Zig Package** task with: +- **Run Step:** *(blank)* — runs `zig build`, which hits the default `ziglings` + step + +For a single exercise use: +- **Run Step:** *(blank)* +- **User Options:** `n=42` + +This produces `zig build -Dn=42`. + +Alternatively, if you have step discovery enabled, **Zig Build: ziglings** +appears automatically and covers the "run all" case with one click. + +<a id="recipe-debug"></a> +### Debug a binary that isn't in zig-out/bin + +Create a **Zig Debug** task and set **Program** explicitly: + +- `zig-out/bin/my-tool` (relative to Working Directory) +- or an absolute path + +When the field is left blank the extension checks `build.zig.zon` for the +package name and probes `zig-out/bin/<name>`. If your binary name doesn't +match the package name, set the path manually. + +--- + +<a id="clean-action"></a> +## Clean action + +Every template task includes a Clean action. It: + +1. Checks that the working directory is a real absolute path inside the current + workspace. Clean refuses to run if the path resolves to `/`, `$HOME`, or + anywhere outside the workspace root, and shows a warning instead. +2. If the project's `build.zig` exposes an `uninstall` step (already in the + step discovery cache), runs `zig build uninstall` first. +3. Removes `.zig-cache`, `zig-cache`, and `zig-out` with `rm -rf`. + +The [Current Zig File](#current-zig-file) automatic task's Clean action +applies the same logic but targets the nearest ancestor directory that contains +a `build.zig`, rather than a configured working directory. + +--- + +<a id="inline-issues"></a> +## Inline issue reporting + +Compiler and test errors are shown as inline annotations in the editor using +the pattern: + +``` +<file>:<line>:<column>: error: <message> +<file>:<line>:<column>: warning: <message> +``` + +This covers output from `zig build`, `zig build test`, `zig run`, `zig test`, +and `zig fmt` (non-`--check` mode). + +`zig fmt --check` only prints filenames, not line numbers, so it does not +produce inline annotations. + +For the **Zig Watch** template, annotations are populated from the first build +cycle only. Subsequent automatic rebuilds do not update them — stop and restart +the task to refresh. + +--- + +<a id="settings"></a> +## Settings reference + +Settings live in two places: + +- **Nova Preferences → Extensions → Zig** — global defaults for all projects. +- **Project Settings → Zig** — workspace-specific overrides. These take + precedence over the global settings for the open project. + +### Tooling + +| Setting | Description | +|---|---| +| Zig Executable | Absolute path to `zig`. Leave blank to discover from `PATH`. | +| ZLS Executable | Absolute path to `zls`. Leave blank to discover from `PATH`. | +| LLDB DAP Executable | Absolute path to `lldb-dap`. Leave blank to discover via `xcrun` or `PATH`. | + +### Language Server + +| Setting | Default | Description | +|---|---|---| +| Enable ZLS | on | Enable diagnostics, completion, hover, go-to-definition, and formatting via ZLS. | +| Build On Save | off | Allow ZLS to run its build/check runner when you save a file. | +| Debug Server Messages | off | Log ZLS protocol traffic to the Extension Console (for troubleshooting). | + +### Debug Adapter + +| Setting | Default | Description | +|---|---|---| +| Enable Proxy Log | off | Write lldb-dap proxy traffic to a log file. For extension development only. | + +### Tasks + +| Setting | Default | Description | +|---|---|---| +| Discover Build Steps | on | Run `zig build --list-steps` and surface each step as a task. Disable for projects where executing `build.zig` on activation is undesirable. | |
