# AGENTS.md - SCL Language Server (Unified) This is a unified Neovim/LazyVim plugin for Siemens SCL language support. ## Project Overview The unified `scl_lsp` project provides: - **LSP Server** - Language Server Protocol implementation - **Linter** - Diagnostics and code validation - **Formatter** - Document formatting - **Syntax Highlighting** - Tree-sitter based - **Auto-completion** - blink.cmp integration with smart context-aware completions - **Auto-prefix** - Automatic `#` prefixing for variables - **Workspace Scanning** - Automatic scanning of UDTs (.udt) and Global DBs (.db) ## Reference Project for Testing For testing and referencing SCL, UDT, DB, and XML files, use the reference project at: ``` ~/dev/siemens/projects/scl_lang_support_lazyvim_ref_project ``` This project contains example SCL files, UDT definitions, and global data blocks. ## Project Structure ``` scl_lsp/ ├── src/ # LSP server implementation │ ├── main.lua # Entry point, protocol handling │ ├── parser.lua # Regex-based SCL parser │ ├── treesitter.lua # Tree-sitter integration │ ├── diagnostics.lua # Linter diagnostics │ ├── formatter.lua # Document formatter │ ├── json.lua # JSON encoder/decoder │ └── plc_json.lua # External UDT loading ├── lua/ │ ├── scl/ # Neovim plugin modules │ │ ├── init.lua # Main plugin setup │ │ ├── auto_prefix.lua # Auto-prefix variables with # │ │ ├── blink_cmp_source.lua # blink.cmp completion source │ │ ├── db_parser.lua # Global DB (.db) parser │ │ ├── fb_parser.lua # Function Block parser │ │ ├── udt_parser.lua # UDT (.udt) parser │ │ ├── variables.lua # Local variable extraction │ │ ├── workspace_types.lua # Workspace scanning (UDTs, DBs, FBs) │ │ └── multiline_params.lua # Multiline parameter filling │ └── scl_lsp/ │ ├── init.lua # Unified plugin setup │ └── plugins/ │ └── scl.lua # LazyVim plugin spec ├── queries/ # Tree-sitter queries │ ├── highlights.scm │ ├── indents.scm │ ├── folds.scm │ ├── locals.scm │ └── tags.scm ├── grammar.js # Tree-sitter grammar └── tree-sitter.json # Parser config ``` ## Key Modules ### Parser Modules | Module | Purpose | |--------|---------| | `udt_parser.lua` | Parses `.udt` files to extract TYPE definitions and STRUCT members | | `db_parser.lua` | Parses `.db` files to extract DATA_BLOCK definitions and VAR members | | `fb_parser.lua` | Parses `.scl` files to extract FUNCTION_BLOCK and FUNCTION interfaces | | `variables.lua` | Extracts local variables from VAR sections | ### Completion System | Module | Purpose | |--------|---------| | `blink_cmp_source.lua` | Main completion source for blink.cmp. Handles: | | | - Local variables (with # prefix after BEGIN) | | | - UDT types (quoted: "MyUDT") | | | - UDT members (after dot: #var.member) | | | - Global DB names (available in general completion) | | | - Global DB members (after quote+dot: "DBName".member) | | | - FB parameter completions (inside FB calls) | | | - Basic SCL types | ### Workspace Scanner | Module | Purpose | |--------|---------| | `workspace_types.lua` | Scans project for: | | | - `.udt` files (UDT types) | | | - `.db` files (Global Data Blocks) | | | - `.scl` files (Function Blocks/Functions) | | | - Uses project markers to find project root | ## Auto-Completion Features ### Trigger Characters - `#` - Local variables (after BEGIN) - `.` - Member access (UDT/DB members) - `"` - Global DB names and member access - `(` - FB/Function parameter completion - ` ` (space) - General completion (variables, UDTs, DBs, types) ### Completion Contexts 1. **Variable Completion** (after space or at start) - Local variables from VAR sections - UDT type names (quoted) - Global DB names (wrapped in quotes automatically) - Basic SCL types 2. **Member Completion** (after `.`) - UDT members (resolves through nested types) - DB members (resolves through nested types) - Supports multi-level nesting: `#var.member.submember` 3. **Global DB Completion** - Type `"` then select DB → shows DB members - Or type space → select DB from list → automatically wrapped in quotes 4. **FB Parameter Completion** (after `fbName(`) - Input parameters (`:=`) - InOut parameters (`:=`) - Output parameters (`=>`) ### Special Features - **Auto-Prefix**: Adds `#` to variables automatically after BEGIN - **Quote Wrapping**: DB names selected from general completion are automatically wrapped in quotes - **Nested Resolution**: Multi-level member path resolution for both UDTs and DBs ## Development ### Running the LSP Server ```bash # Direct execution lua src/main.lua # Via shell script ./scl_lsp.sh # With test mode lua src/main.lua --test ``` ### Testing ```bash # Tree-sitter parser npm test tree-sitter generate # Test file parsing tree-sitter parse corpus/test/main_org_block.scl ``` ### Key Patterns - **LSP Protocol**: JSON-RPC over stdin/stdout in `src/main.lua` - **Diagnostics**: `src/diagnostics.lua` - validates SCL code - **Formatter**: `src/formatter.lua` - formats SCL documents - **Syntax**: Tree-sitter queries in `queries/` - **Plugin Setup**: `lua/scl_lsp/init.lua` - LazyVim integration ## Configuration See `README.md` for configuration options and usage. ## 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/ |