After splitting from the original scl_lsp repo, update for plugin-only scope: - README.md: focused on Neovim plugin installation, configuration, commands, keybindings, and editor features - AGENTS.md: plugin-only project structure and conventions - test/run_tests.lua: run only plugin tests (udt, db, fb, integration) - test/test_integration.lua: remove plc_json dependency (server module) - queries/: move from queries/*.scm to queries/scl/*.scm (nvim-treesitter per-language convention) - ftdetect/scl.vim: add filetype detection for .scl/.udt/.db files
221 lines
8.0 KiB
Markdown
221 lines
8.0 KiB
Markdown
# tia-lsp.nvim - Neovim Plugin for Siemens TIA Portal
|
|
|
|
A Neovim/LazyVim plugin that launches the [`tia-lsp`](https://gitea.l-tech.rs/lazar/tia-lsp) language server and adds editor-specific features for Siemens TIA Portal languages. Currently supports **SCL** (Structured Control Language), with planned support for **STL/AWL**, **LAD**, and **FBD**.
|
|
|
|
## 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 |
|
|
| **Attribute Block Toggle** | Interactive expand/collapse of `{...}` blocks with `<Leader>xa` |
|
|
| **Tree-sitter Highlighting** | Syntax highlighting via tree-sitter queries |
|
|
|
|
## Installation
|
|
|
|
The plugin auto-detects the mason-installed `tia-lsp` executable via `vim.fn.exepath("tia-lsp")` and falls back to `lua <server_path>` for manual installs.
|
|
|
|
### LazyVim + Mason (Recommended)
|
|
|
|
1. Add the mason registry as a lazy.nvim plugin:
|
|
```lua
|
|
-- ~/.config/nvim/lua/plugins/tia-mason-registry.lua
|
|
return {
|
|
url = "https://gitea.l-tech.rs/lazar/tia-mason-registry.git",
|
|
name = "tia-mason-registry",
|
|
lazy = false, -- must be available before mason setup
|
|
}
|
|
```
|
|
|
|
2. Register the registry with mason:
|
|
```lua
|
|
-- ~/.config/nvim/lua/plugins/mason.lua
|
|
return {
|
|
"mason-org/mason.nvim",
|
|
opts = {
|
|
registries = {
|
|
"file:" .. vim.fn.expand("~/.local/share/nvim/lazy/tia-mason-registry"),
|
|
"github:mason-org/mason-registry",
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
3. Add the plugin:
|
|
```lua
|
|
-- ~/.config/nvim/lua/plugins/tia-lsp.lua
|
|
return {
|
|
"lazar/tia-lsp.nvim",
|
|
ft = "scl",
|
|
lazy = true,
|
|
dependencies = {
|
|
"neovim/nvim-lspconfig",
|
|
"nvim-treesitter/nvim-treesitter",
|
|
"saghen/blink.cmp",
|
|
},
|
|
config = function()
|
|
require("tia_lsp").setup({
|
|
lsp = {
|
|
on_attach = function(client, bufnr)
|
|
-- custom keymaps
|
|
end,
|
|
},
|
|
cmp = true, -- Enable blink.cmp integration
|
|
workspace_types = true, -- Enable workspace UDT scanning
|
|
auto_prefix = true, -- Enable auto-# prefixing
|
|
debug = false,
|
|
})
|
|
end,
|
|
}
|
|
```
|
|
|
|
4. Install:
|
|
```
|
|
:MasonInstall yq " one-time prerequisite for file: registry
|
|
:MasonInstall tia-lsp " installs the LSP server
|
|
```
|
|
|
|
5. Verify: open a `.scl` file and run `:LspInfo` — `tia_lsp` should be attached.
|
|
|
|
### Manual Setup (without Mason)
|
|
|
|
```lua
|
|
require("tia_lsp").setup({
|
|
server_path = "/path/to/tia-lsp/src/main.lua", -- only used if tia-lsp is not on PATH
|
|
ts_parser_url = "https://gitea.l-tech.rs/lazar/tia-lsp.git",
|
|
cmp = true,
|
|
workspace_types = true,
|
|
auto_prefix = true,
|
|
})
|
|
```
|
|
|
|
## Configuration Options
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `server_path` | string | `~/dev/tia-lsp/src/main.lua` | Path to LSP server (only used if `tia-lsp` is not on PATH) |
|
|
| `ts_parser_url` | string | `file://~/dev/tia-lsp` | URL passed to nvim-treesitter for the SCL parser source |
|
|
| `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 |
|
|
| `:SCLFormat` | Format current SCL file |
|
|
| `:SCLToggleAttrBlock` | Toggle attribute block under cursor |
|
|
| `:SCLExpandAllAttrBlocks` | Expand all `{...}` blocks in buffer |
|
|
| `:SCLCollapseAllAttrBlocks` | Collapse all matching attribute blocks |
|
|
|
|
## 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>xa` | Toggle attribute block under cursor |
|
|
| `<Leader>xae` | Expand all attribute blocks |
|
|
| `<Leader>xac` | Collapse all attribute blocks |
|
|
| `<leader>fw` | Workspace Symbols (Telescope) |
|
|
| `<leader>ca` | Code Actions |
|
|
|
|
## Attribute Block Toggle
|
|
|
|
Interactive expand/collapse of SCL variable attribute blocks:
|
|
|
|
```scl
|
|
-- Before: Verbose attributes
|
|
statCounter{EXTERNALACCESSIBLE := 'false'; EXTERNALVISIBLE := 'false'} : Int;
|
|
|
|
-- After: Collapsed
|
|
statCounter{...} : Int;
|
|
```
|
|
|
|
**Usage:**
|
|
- Place cursor inside any `{...}` block
|
|
- Press `<Leader>xa` to toggle expand/collapse
|
|
- Use `<Leader>xae` to expand all blocks in buffer
|
|
- Use `<Leader>xac` to collapse all blocks
|
|
|
|
**Note:** Collapsed blocks are automatically expanded before saving to preserve full content on disk.
|
|
|
|
## Filetype Detection
|
|
|
|
The plugin includes `ftdetect/scl.vim` which registers the following file extensions as `scl` filetype:
|
|
- `*.scl` — SCL source files
|
|
- `*.udt` — User-defined type files
|
|
- `*.db` — Data block files
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
tia-lsp.nvim/
|
|
├── lua/
|
|
│ ├── tia_lsp/ # Plugin entry point
|
|
│ │ ├── init.lua # Main setup (vim.lsp.start, exepath detection)
|
|
│ │ └── plugins/
|
|
│ │ └── scl.lua # LazyVim plugin spec (SCL filetype)
|
|
│ └── tia/ # Language modules (shared across TIA languages)
|
|
│ ├── auto_prefix.lua # Auto-# prefixing
|
|
│ ├── attr_toggle.lua # Attribute block expand/collapse
|
|
│ ├── blink_cmp_source.lua # blink.cmp completion source
|
|
│ ├── builtin_instructions.lua
|
|
│ ├── db_parser.lua # Global DB parser
|
|
│ ├── fb_parser.lua # Function Block parser
|
|
│ ├── multiline_params.lua # Multiline parameter filling
|
|
│ ├── udt_parser.lua # UDT parser
|
|
│ ├── variables.lua # Variable extraction
|
|
│ └── workspace_types.lua # Workspace scanning
|
|
├── queries/
|
|
│ └── scl/ # Tree-sitter queries (per-language)
|
|
│ ├── highlights.scm # Syntax highlighting
|
|
│ ├── indents.scm # Indentation
|
|
│ ├── folds.scm # Code folding
|
|
│ ├── locals.scm # Variable scoping
|
|
│ └── tags.scm # Navigation tags
|
|
├── ftdetect/
|
|
│ └── scl.vim # Filetype detection
|
|
└── test/ # Plugin tests
|
|
├── run_tests.lua
|
|
├── test_harness.lua
|
|
├── test_udt.lua
|
|
├── test_db.lua
|
|
├── test_fb.lua
|
|
└── test_integration.lua
|
|
```
|
|
|
|
## Requirements
|
|
|
|
- **Neovim 0.11+** (uses `vim.lsp.start()`)
|
|
- **tia-lsp** — the LSP server (install via mason or manually)
|
|
- **nvim-treesitter** — Syntax highlighting
|
|
- **blink.cmp** — Optional, for completion
|
|
- **Lua 5.1+** — LSP server runtime
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
lua test/run_tests.lua
|
|
```
|
|
|
|
Tests use files from a reference project (override with `SCL_REF_PROJECT=/path/to/ref lua test/run_tests.lua`).
|