Aller au contenu principal

Language Server (LSP)

The OPC UA Modeler ships a fully standard Language Server Protocol server. VS Code users get it automatically via the VS Code Extension. For all other editors — Neovim, Zed, Emacs, or any LSP-compliant tool — this page covers manual setup.

Starting the server​

# stdio mode — for editors that spawn the server as a child process
opcua-modeler lsp --stdio

# socket mode — for multi-client / WebSocket setups (e.g. browser-based editors)
opcua-modeler lsp --socket 7000

Neovim (nvim-lspconfig)​

Add the following to your Neovim configuration (Lua):

local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")

-- Register the custom server if not already known
if not configs.opcua_modeler then
configs.opcua_modeler = {
default_config = {
cmd = { "opcua-modeler", "lsp", "--stdio" },
filetypes = {
"yaml", -- general YAML; restrict via root_dir if needed
},
root_dir = lspconfig.util.root_pattern("*.model.yaml", "*.nodeset.yaml", ".git"),
single_file_support = true,
settings = {},
},
}
end

lspconfig.opcua_modeler.setup({})

Tip: If you only want the OPC UA LSP to activate on .model.yaml / .nodeset.yaml files, add a custom filetypes detection or use vim.filetype.add to map those extensions to a dedicated filetype (e.g. opcua_yaml) before calling setup.


Zed​

Add the following to your Zed settings.json (or ~/.config/zed/settings.json):

{
"lsp": {
"opcua-modeler": {
"binary": {
"path": "opcua-modeler",
"arguments": ["lsp", "--stdio"]
}
}
},
"languages": {
"YAML": {
"language_servers": ["opcua-modeler", "..."]
}
}
}

Emacs​

With eglot (built-in from Emacs 29+)​

(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(yaml-mode . ("opcua-modeler" "lsp" "--stdio"))))

;; Auto-start eglot when opening model files
(add-hook 'yaml-mode-hook #'eglot-ensure)

With lsp-mode​

(with-eval-after-load 'lsp-mode
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection
'("opcua-modeler" "lsp" "--stdio"))
:activation-fn (lsp-activate-on "yaml")
:server-id 'opcua-modeler)))

Socket / multi-client mode​

For setups where multiple editors or a browser-based editor connect to a single shared server, use the --socket flag:

# Start a persistent LSP server on port 7000
opcua-modeler lsp --socket 7000

Clients connect via WebSocket or TCP to localhost:7000. The server maintains isolated per-connection state (document buffers, debounce timers, capability flags) while sharing the expensive OPC UA address space cache across all connections.


Diagnostics reference​

The server emits diagnostics using structured codes in the form DSL-E-*, DSL-W-*, and DSL-I-*.

PrefixSeverityDescription
DSL-E-*ErrorMust be fixed — invalid or illegal model construct
DSL-W-*WarningPotentially incorrect — shown by default, suppressed with --quiet
DSL-I-*InfoStyle / conformance hints — hidden by default, shown with --style

Semantic checks performed​

The following semantic diagnostics are produced by Layer 2:

CheckExample message
Invalid typeDefinition referenceUnknown type 'MySensor' — not found in address space
Invalid subtypeOf reference'MyBase' is not an ObjectType
Broken organizedBy / componentOf browse pathPath 'Root/Objects/Tank' does not exist in node tree
Invalid promotedToMandatory entry'Status' is not an optional member of 'SensorType'
Duplicate initializers: variable: entriesDuplicate initializer path 'Parameters/MaxValue'
Duplicate $anchor IDsAnchor 'pump1' is already defined on line 42
Self-referencing placementNode cannot reference itself or its own subtree as placement parent
YAML syntax errorYAML parse error at line 12: unexpected ':'

Suppressing specific codes​

Use the --silence flag on the CLI, or configure suppressions in your project:

# Suppress a specific warning code
opcua-modeler generate --silence DSL-W-001

# Suppress all warnings matching a prefix
opcua-modeler generate --silence DSL-W

Address space cache​

The server loads the OPC UA base address space (and all imported companion specs) once and caches it across all open connections. This means:

  • The first open of a model file may take a second while the address space loads
  • Subsequent completions and diagnostics are near-instant

The cache is invalidated when the list of namespaces: imports in your file changes.