OpenSCENARIO 2.0 for VS Code
Editing support for ASAM OpenSCENARIO 2.0 (.osc), backed by the osc-lsp
language server from osc2r2.
Features
- Diagnostics — lexical, syntax, name-resolution and type errors as you type,
including errors coming from an
imported file, and a name read off a declaration
that does not have it (keep(it.speeed == 10kph)).
- Hover / Go to Definition — for types, fields, actions, modifiers and enum
members, across files, following
inherits: car.drive() reaches an action declared
on whatever car inherits from. Hovering a struct, actor or other declaration
lists what it holds, inherited members included.
it inside a constraint — keep(it.speed == 10kph) resolves: hover says which
declaration it stands for, and speed has a definition to jump to, following field
types into whichever file declares them. A with: block moves it to what the block
is attached to — a field's own type, or the behaviour a do step invokes — while a
bare name in the same constraint still means the enclosing declaration's own field.
do steps and with: blocks — both halves of car.assign_position(), the
scenario a bare do run_car() composes, and a modifier applied under a step
(slow(2)), which is declared on the actor the step is invoked on.
- Outline — the declarations in the file.
- Completion — keywords, type names, field names, enum members and units,
chosen from what the cursor is in the middle of.
- Find References — for type names, across the workspace: the declaring file and
every
.osc under the open folders that imports it.
- Rename — for type names, within the file. Deliberately not across it: a rename
has to reach every use, and a project reaching outside the open folders has uses
the workspace scan never sees.
- Semantic highlighting — classification by position in the tree, so a reserved
word used as a name is drawn as a name.
- Signature help — the parameters of the call being written.
The prelude is the built-in domain model by default, so vehicle, speed and the
other common names resolve in a self-contained file. Point osc2.standardOscPath at
the ASAM standard.osc to use that instead.
Requirements
The analysis is done by the osc-lsp executable, which this extension starts and
talks to. It ships inside the extension, so there is nothing to install
separately: the Marketplace serves the package built for your platform, and the server
in it is the one that gets started.
The platforms carrying a server are Linux, macOS and Windows on x86-64, and Linux and
macOS on ARM64. The Linux builds are glibc, so they do not run on Alpine or another
musl distribution.
Somewhere else is still possible — a platform not in that list, or a build of your own.
The lookup order is:
osc2.server.path, if set — and if that path is not runnable it says so rather
than quietly starting something else;
- the copy shipped inside this extension (
server/osc-lsp);
osc-lsp on PATH;
target/release/osc-lsp, then target/debug/osc-lsp, under the workspace folder.
With no server at all the extension is a syntax highlighter, and it says so rather
than letting the missing diagnostics read as "this file is fine".
The extension does not run in an untrusted or virtual workspace: the server is an
executable, a workspace can name it, and it needs real files on disk to resolve
import against.
Settings
| Setting |
Default |
What it does |
osc2.server.path |
"" |
Where the osc-lsp executable is. Empty searches the list above. |
osc2.server.logLevel |
info |
The server's own log level (OSC_LSP_LOG), sent to the output channel. |
osc2.standardOscPath |
"" |
The standard.osc to use as the prelude. Empty uses the built-in domain model. |
osc2.entryScenario |
main |
The scenario parameter binding starts from. |
osc2.diagnostics.enable |
true |
Publish diagnostics. |
osc2.diagnostics.includeBinding |
false |
Also report unresolved behaviour calls and unsatisfiable keep() constraints. |
osc2.gotoDefinition.stayPut |
true |
Go to definition on a position that names nothing stays where it is, instead of reporting "No definition found". |
osc2.trace.server |
off |
Trace the JSON-RPC traffic (for debugging the extension). |
${workspaceFolder} and a leading ~ are expanded in both path settings, and a
relative path is resolved against the workspace folder.
osc2.gotoDefinition.stayPut works by answering with the cursor's own position, which
is the only thing the protocol offers in place of "nothing to do". For .osc files the
extension therefore also defaults editor.gotoLocation.alternativeDefinitionCommand to
empty, which is what keeps VS Code from opening a references peek in its place. Two
trades come with that, and both are settings you can put back:
F12 on a declaration's own name now does nothing rather than peeking its
references (Shift+F12 still does), and
Ctrl/Cmd-hovering a keyword may draw it as a link, since the
editor asks the same provider to decide that.
A name that is a name and resolves to nothing still says so — that message is the
feature working.
The server reads these once, at startup. Changing one prompts to restart it;
OpenSCENARIO 2: Restart Language Server does the same on demand, and
OpenSCENARIO 2: Show Language Server Log opens the channel it logs to.
Terms of use are in LICENSE.txt. THIRD-PARTY-NOTICES.txt carries the licences of
the open-source crates compiled into the bundled server; the licences of this
extension's own JavaScript dependencies travel with them under node_modules.
ASAM, OpenSCENARIO and OpenDRIVE are trademarks of ASAM e.V. This project is not
affiliated with or endorsed by ASAM e.V.