TwinSight
TwinCAT Structured Text support for Visual Studio Code
Overview
This extension brings TwinCAT Structured Text (ST) language support to VS Code. The long-term goal is to enable full editing of ST code directly in VS Code. Currently, the extension provides syntax highlighting, diagnostics and navigation features. Editing is not yet supported, i.e. diagnostics will not be updated on the fly.
Use the Implement interface quick fix on a function block's IMPLEMENTS clause to generate missing methods and properties. Save edits and reload the solution to refresh the analysis before requesting further fixes.
- Browse and navigate TwinCAT ST codebases with semantic awareness.
- Snippets for common declarations and control-flow statements are available in ST files through completion (for example,
FUNCTION_BLOCK, IF, and FOR).
- No direct editing of TwinCAT XML files (
.TcPOU, .TcDUT, .TcGVL, etc).
- Conversion required: You must convert your TwinCAT XML sources to
.st files before using the language features.
Getting Started
Install the extension from the VS Code Marketplace.
Open your TwinCAT solution in VS Code.
The extension will detect your TwinCAT solution file (e.g., .sln).
Convert TwinCAT XML files:
On first use, you will be prompted to convert all TwinCAT XML source files to .st files.
The language server will now launch and provide navigation for your .st files.
Library dependencies
The extension reads TwinCAT library files directly. Libraries can come from an
installed TwinCAT system, local paths, URLs, Git repositories, or the Beckhoff
package feed.
Installed libraries
On Windows, the extension discovers installed Managed Libraries by default. To
use additional Managed Library roots, set twinsight.managedLibrariesPath in
VS Code settings.
Local files and URLs
To use libraries stored locally or available online, run TwinSight: Open
workspace configuration and add them to librarySources in
twinsight.yaml. For example:
librarySources:
- libs
- vendor/Example.library
- /opt/twincat/libraries
- https://github.com/tcunit/TcUnit/releases/download/1.3.1/TcUnit.library
Entries can be files or directories, with paths either absolute or relative to
twinsight.yaml. Directories are searched recursively. File URLs and HTTPS
URLs for individual library files are also supported. Supported extensions are
.library, .compiled-library, .compiled-library-ge33, and
.compiled-library-v3. Some older libraries use an encrypted format the reader
does not yet handle; see format limitations.
Git repositories
Add Git-hosted libraries to repositories in the workspace's twinsight.yaml.
You can also use the add/remove repository commands. The optional libraryPaths
entries are relative to the checkout:
repositories:
- url: https://example.com/team/libraries.git
tag: main
libraryPaths: [libraries]
Only configured Git repositories are restored and scanned; cached declaration
repositories are ignored unless configured.
Beckhoff package feed
The extension resolves PLC library references against local sources first. For
unresolved Beckhoff Tc2_ and Tc3_ references, it looks up the exact package
ID TwinCAT.XAE.PLC.Lib.<libraryName> and verifies the extracted PLC library's
identity and version. Dependencies are resolved recursively. If the requested
PLC library version is unavailable, the extension can use a newer version and
reports substitutions together after restoration. Package versions and PLC
library versions are distinct. Use
TwinSight: Sign in to Beckhoff package feed to configure the feed URL and
credentials. Run it again to change them; the current URL and username are
prefilled.
Credentials are stored in VS Code secret storage. A non-default feed URL is
stored as beckhoffFeedUrl in twinsight.yaml; otherwise, the public Stable
feed is used. Signing out removes the credentials but keeps the workspace URL.
On Linux, package extraction requires msiextract from msitools.
Reload the solution after changing library configuration. For supported formats
and other details, see
dependency management.
An existing twinsight.json is automatically converted to YAML on first use;
the original JSON file is retained, and obsolete packageReferences are removed.
The Red Hat YAML extension provides schema validation and completion.
Diagnostic suppression
Suppress specific diagnostic codes in the workspace's twinsight.yaml:
diagnosticSuppressions:
- code: W0001
files: ["st/dev/Tests/**/*.st"]
Warning codes are:
| Code |
Warning |
| W0001 |
Access to another function block's local variable |
| W0002 |
Self-assignment of a direct identifier |
| W0004 |
Ambiguous name |
| W0005 |
Low global_init_slot value |
| W0006 |
Ineffective global_init_slot attribute |
| W0007 |
Duplicate struct field initialization |
| W0008 |
Interface inheritance using IMPLEMENTS |
| W0009 |
Constant without an initial value |
| W0010 |
Duplicate enum value |
| W0011 |
Signed-to-unsigned conversion may change sign |
| W0012 |
Unsigned-to-signed conversion may change sign |
| W0013 |
Conversion may lose information |
| W0014 |
String truncation |
| W0015 |
WSTRING contains non-representable characters |
Paths are glob patterns relative to the folder containing twinsight.yaml; omit files
to suppress a code in all published diagnostics, including external files. An
empty files array matches nothing. Suppression affects displayed diagnostics,
not analysis or compilation.
Run TwinSight: Reload solution after editing the configuration.
Development
Install dependencies:
pnpm install
Generate the Structured Text parser after changing src/StructuredText.g4:
pnpm generate:grammar
You can also run the VS Code task generate:grammar from Terminal: Run Task.
Grammar generation is handled by the repo-local antlr-ng dependency. Do not use the ANTLR VS Code extension to generate committed parser files, because it may use a different ANTLR version. Generated parser files are written to src/generated; temporary .interp files are removed by the generation script.
Restart VS Code after parser changes if the extension host is already running.
To edit the TextMate grammar, modify grammars/st.tmLanguage.yaml and convert it:
pnpx js-yaml grammars/st.tmLanguage.yaml > grammars/st.tmLanguage.json
Verify changes before committing:
pnpm compile
pnpm test
Format the code before committing:
pnpm format:fix
pnpm lint (also part of pnpm compile) fails when Prettier reports
unformatted files. ESLint handles only non-formatting rules; Prettier owns
layout. Editor integration is preconfigured in .vscode/settings.json, so
format-on-save uses the same settings.
Feedback and contributions are welcome!