SCL Language Server - Unified Plugin for Siemens SCL
A comprehensive Neovim/LazyVim plugin providing Language Server Protocol (LSP), Linting, Formatting, and Syntax Highlighting for Siemens SCL (Structured Control Language) used in Siemens TIA Portal.
Features
LSP (Language Server Protocol)
| Feature |
Description |
| Hover |
Press K to see variable type and struct fields |
| Completion |
# for variables, . for struct fields, ( for functions |
| Go to Definition |
gd jump to variable declaration |
| Document Symbols |
Shows functions, variables, types |
| Workspace Symbols |
Search across all .scl files with fuzzy matching |
| Semantic Tokens |
Keywords, variables highlighted |
| Inlay Hints |
Shows variable types after declaration |
| External UDT |
Load types from .plc.json or data_types/ folder |
Linter (Diagnostics)
| Feature |
Description |
| Undefined Variables |
Detects variables used without declaration |
| Invalid # Prefix |
Detects # prefix in VAR sections |
| Unknown Types |
Warns about unknown data types |
| Type Validation |
Basic type checking |
Formatter
| Feature |
Description |
| Document Formatting |
Format entire SCL files |
| Indentation |
Proper block indentation |
| Keyword Casing |
Maintains SCL keyword casing |
Syntax Highlighting
- Full SCL syntax support via tree-sitter
- ORGANIZATION_BLOCK, FUNCTION_BLOCK, FUNCTION definitions
- Variable declarations (VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_TEMP, etc.)
- Control structures (IF/THEN/ELSE, CASE, FOR, WHILE, REPEAT)
- Code regions and comments
- All SCL data types and operators
Additional Features
| Feature |
Description |
| Auto-Prefix |
Automatically adds # prefix to local variables (like TIA Portal) |
| Multiline Parameters |
Fill FB/Function call parameters across multiple lines with <Space>mp or :SCLMultilineParams |
| Tab Navigation |
Jump between parameters with <Tab> in insert mode |
| Workspace UDT Scanner |
Scans project for user-defined types (.udt files) |
| Workspace Global DB Scanner |
Scans project for global data blocks (.db files) |
| blink.cmp Integration |
Smart completion source for blink.cmp |
Installation
LazyVim
Manual Setup
Configuration Options
| Option |
Type |
Default |
Description |
server_path |
string |
~/dev/scl_lsp/src/main.lua |
Path to LSP server |
lsp.on_attach |
function |
nil |
Custom LSP attach callback |
lsp.formatting |
boolean |
false |
Enable format command |
cmp |
boolean |
true |
Enable blink.cmp integration |
workspace_types |
boolean |
true |
Enable workspace UDT scanning |
auto_prefix |
boolean |
true |
Enable auto-# prefixing |
project_root |
string |
nil |
Custom project root |
library_paths |
table |
{} |
Additional library paths |
debug |
boolean |
false |
Enable debug logging |
Commands
| Command |
Description |
:SCLShowVariables |
Show local variables in current file |
:SCLShowWorkspaceTypes |
Show workspace UDTs, FBs, and Global DBs count |
:SCLRescanWorkspaceTypes |
Rescan workspace for types and DBs |
:SCLPrefixWord |
Manually prefix current word with # |
:SCLMultilineParams |
Fill multiline parameters for FB/Function call |
:LspSCLFormat |
Format current SCL file |
:SCLGeneratePlcJson |
Generate plc.data.json from data_types/ |
Keybindings
| Key |
Action |
K |
Hover (show variable info) |
gd |
Go to Definition |
<leader>s |
Document Symbols |
<leader>w |
Workspace Symbols |
<Space>mp |
Fill multiline FB/Function parameters (insert mode) |
<Tab> |
Jump to next parameter (insert mode) |
<leader>fw |
Workspace Symbols (Telescope) |
<leader>ca |
Code Actions |
External UDT Support
Option 1: Create .plc.json
Option 2: Auto-scan data_types/ folder
The LSP automatically scans for SCL files in data_types/ folder and extracts TYPE definitions.
Option 3: Generate .plc.json
Global Data Block Support
The plugin automatically scans for .db files in the workspace and provides auto-completion for global data blocks and their members.
How it works
- Workspace Scanning: When opening a
.scl file, the plugin scans the project for .db files
- DB Parsing: Parses
DATA_BLOCK definitions and extracts members from VAR sections
- Auto-completion: Provides smart completion for DB names and members
Usage
- Type a space or
# to trigger completion - global DB names appear alongside local variables
- Type
" followed by a DB name to get member completions
- Access nested members:
"MyDB".member.submember
Example
Project Structure
Building Tree-sitter Parser
SCL Code Example
Requirements
- Neovim 0.9+
- nvim-lspconfig - LSP client
- nvim-treesitter - Syntax highlighting
- blink.cmp - Optional, for completion
- Lua 5.1+ - LSP server runtime