chore: adjust README, AGENTS, and test runner for server-only scope
After splitting from the original scl_lsp repo, update documentation and test infrastructure to reflect the server-only scope of this repo. - README.md: focused on LSP server features, tree-sitter grammar, running the server, and Mason installation reference - AGENTS.md: server-only project structure and conventions - test/run_tests.lua: run only server tests (formatter, plc_json)
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
# AGENTS.md - tia-lsp
|
||||
|
||||
A Neovim/LazyVim plugin and standalone LSP server for Siemens TIA Portal languages. Currently supports **SCL**; planned support for STL/AWL, LAD, FBD. The project is split into two repos:
|
||||
|
||||
- **`tia-lsp`** (this repo) — LSP server (`src/`) + tree-sitter grammar (`grammar.js`). Editor-agnostic.
|
||||
- **`tia-lsp.nvim`** — Neovim plugin (`lua/`) that launches the server and adds editor features.
|
||||
A standalone LSP server for Siemens TIA Portal languages. Currently supports **SCL**; planned support for STL/AWL, LAD, FBD. This repo is the server only (`src/` + tree-sitter grammar). The companion Neovim plugin lives in `tia-lsp.nvim`.
|
||||
|
||||
## Build/Lint/Test Commands
|
||||
|
||||
@@ -20,16 +17,11 @@ tree-sitter parse <file.scl> # Parse single SCL file
|
||||
|
||||
# Lua Linting
|
||||
luacheck src/ # Lint LSP server code
|
||||
luacheck lua/tia/ # Lint plugin modules
|
||||
|
||||
# Unit & Integration Tests
|
||||
lua test/run_tests.lua # Run all tests
|
||||
lua test/test_udt.lua # Run UDT parser tests
|
||||
lua test/test_db.lua # Run DB parser tests
|
||||
lua test/test_fb.lua # Run FB parser tests
|
||||
# Unit Tests
|
||||
lua test/run_tests.lua # Run all server tests
|
||||
lua test/test_formatter.lua # Run formatter tests
|
||||
lua test/test_plc_json.lua # Run plc_json tests
|
||||
lua test/test_integration.lua # Run integration tests
|
||||
|
||||
# Reference Project
|
||||
# Tests use files from: ~/dev/siemens/projects/scl_lang_support_lazyvim_ref_project/
|
||||
@@ -49,38 +41,16 @@ tia-lsp/
|
||||
│ ├── plc_json.lua # External UDT/DB loading (language-agnostic)
|
||||
│ ├── builtin_instructions.lua # TIA Portal built-in types
|
||||
│ └── json.lua # JSON encoder/decoder
|
||||
├── lua/tia/ # Neovim plugin (uses require)
|
||||
│ ├── udt_parser.lua # UDT parser
|
||||
│ ├── db_parser.lua # Global DB parser
|
||||
│ ├── fb_parser.lua # Function Block parser
|
||||
│ ├── variables.lua # Variable extraction
|
||||
│ ├── workspace_types.lua # Workspace scanning
|
||||
│ ├── multiline_params.lua
|
||||
│ ├── auto_prefix.lua
|
||||
│ └── attr_toggle.lua
|
||||
├── lua/tia_lsp/ # Plugin entry point
|
||||
│ ├── init.lua # Main plugin setup (vim.lsp.start)
|
||||
│ └── plugins/scl.lua # LazyVim plugin spec
|
||||
├── queries/ # Tree-sitter queries (per-language: queries/scl/)
|
||||
└── grammar.js # Tree-sitter grammar (language name: 'scl')
|
||||
├── grammar.js # Tree-sitter grammar (language name: 'scl')
|
||||
└── test/ # Server tests
|
||||
```
|
||||
|
||||
## Naming Convention
|
||||
|
||||
- **Project name** (repo, Lua module, LSP server, mason package): `tia-lsp` / `tia_lsp` — umbrella for all TIA languages.
|
||||
- **Project name** (repo, LSP server, mason package): `tia-lsp` / `tia_lsp` — umbrella for all TIA languages.
|
||||
- **Language name** (filetype, tree-sitter parser, grammar): `scl` — stays as-is. Future languages (`stl`, `lad`, `fbd`) get their own names.
|
||||
- **LSP client name**: `tia_lsp` (one client handles all TIA languages; dispatches by `filetype` / `languageId`).
|
||||
- **Diagnostic source**: `tia_lsp`.
|
||||
- **Commands**: `:SCLFormat`, `:SCLShowVariables`, etc. — per-filetype prefix. Future: `:STLFormat`, etc.
|
||||
|
||||
## Filetype Detection
|
||||
|
||||
After the split, `ftdetect/scl.vim` will live in `tia-lsp.nvim`. Currently required in Neovim config:
|
||||
```vim
|
||||
au BufRead,BufNewFile *.scl set filetype=scl
|
||||
au BufRead,BufNewFile *.udt set filetype=scl
|
||||
au BufRead,BufNewFile *.db set filetype=scl
|
||||
```
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
@@ -106,13 +76,10 @@ return M
|
||||
- Booleans: prefix with `is_`, `has_` (e.g., `is_udt`, `has_members`)
|
||||
|
||||
### Imports
|
||||
- `lua/tia/` modules: `require("tia.module_name")`
|
||||
- `lua/tia_lsp/` entry: `require("tia_lsp")`
|
||||
- `src/` modules: `dofile(script_path .. "/module.lua")`
|
||||
- External dependencies: wrap in `pcall()` for safety
|
||||
|
||||
### Code Formatting
|
||||
- `lua/tia/` and `lua/tia_lsp/`: 2 spaces indentation
|
||||
- `src/`: tab-based indentation
|
||||
- Max line length: 120 characters
|
||||
- No trailing whitespace
|
||||
@@ -190,6 +157,5 @@ Use the reference project for testing:
|
||||
|
||||
Contains `.scl`, `.db`, `.udt`, and `.xml` files for comprehensive testing of:
|
||||
- LSP features (hover, completion, go-to-definition)
|
||||
- Formatter (`:SCLFormat`)
|
||||
- Attribute block toggle
|
||||
- Formatter
|
||||
- Workspace type scanning
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
# tia-lsp - Language Server for Siemens TIA Portal
|
||||
|
||||
A Neovim/LazyVim plugin and standalone LSP server providing **Language Server Protocol (LSP)**, **Linting**, **Formatting**, and **Syntax Highlighting** for Siemens TIA Portal languages. Currently supports **SCL** (Structured Control Language), with planned support for **STL/AWL**, **LAD**, and **FBD**.
|
||||
A standalone LSP (Language Server Protocol) server for Siemens TIA Portal languages. Currently supports **SCL** (Structured Control Language), with planned support for **STL/AWL**, **LAD**, and **FBD**.
|
||||
|
||||
The project is split into two repos:
|
||||
|
||||
- **`tia-lsp`** (this repo) — the standalone LSP server (`src/`) plus the tree-sitter grammar (`grammar.js`, `src/parser.c`). Speaks JSON-RPC over stdio. Editor-agnostic: usable from Neovim, VS Code, or any LSP client.
|
||||
- **`tia-lsp.nvim`** — the Neovim plugin (`lua/`) that launches the server via `vim.lsp.start()` and adds editor-specific features (auto-prefix, blink.cmp source, workspace UDT scanning, attribute toggle, multiline params).
|
||||
The server speaks JSON-RPC over stdio and is editor-agnostic — usable from Neovim, VS Code, or any LSP client. For Neovim users, the companion plugin [`tia-lsp.nvim`](https://gitea.l-tech.rs/lazar/tia-lsp.nvim) provides seamless integration (auto-prefix, blink.cmp source, workspace scanning, attribute toggle, etc.).
|
||||
|
||||
## Features
|
||||
|
||||
### LSP (Language Server Protocol)
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Hover** | Press `K` to see variable type and struct fields |
|
||||
| **Hover** | Variable type and struct fields |
|
||||
| **Completion** | `#` for variables, `.` for struct fields, `(` for functions |
|
||||
| **Go to Definition** | `gD` jump to function, FB, DB, or UDT definition |
|
||||
| **Go to Definition** | Jump to function, FB, DB, or UDT definition |
|
||||
| **Document Symbols** | Shows functions, variables, types |
|
||||
| **Workspace Symbols** | Search across all `.scl` files with fuzzy matching |
|
||||
| **Semantic Tokens** | Keywords, variables highlighted |
|
||||
@@ -32,13 +29,13 @@ The project is split into two repos:
|
||||
### Formatter
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Document Formatting** | Format entire SCL files with `:SCLFormat` |
|
||||
| **Document Formatting** | Format entire SCL files |
|
||||
| **Multi-line Assignments** | Preserves and formats multi-line expressions with proper alignment |
|
||||
| **FB Call Formatting** | Formats function block calls in multiline style |
|
||||
| **Indentation** | Proper block indentation |
|
||||
| **Keyword Casing** | Maintains SCL keyword casing |
|
||||
|
||||
### Syntax Highlighting
|
||||
### Tree-sitter Grammar
|
||||
- Full SCL syntax support via tree-sitter
|
||||
- Block definitions: ORGANIZATION_BLOCK, FUNCTION_BLOCK, FUNCTION
|
||||
- Variable sections: VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_TEMP, VAR_CONSTANT
|
||||
@@ -50,164 +47,25 @@ The project is split into two repos:
|
||||
- Operators: AND, OR, NOT, XOR, MOD
|
||||
- Comments: line (`//`), block (`(* *)`), C-style (`/* */`)
|
||||
|
||||
### 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 |
|
||||
| **Attribute Block Toggle** | Interactive expand/collapse of `{...}` blocks with `<Leader>xa` |
|
||||
## Running the Server
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
# Start the LSP server (reads JSON-RPC from stdin, writes to stdout)
|
||||
lua src/main.lua
|
||||
|
||||
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. See [Mason installation](#mason-installation) below for the recommended path.
|
||||
|
||||
### LazyVim
|
||||
```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 options
|
||||
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,
|
||||
}
|
||||
# Run server tests
|
||||
make test
|
||||
# or: lua src/main.lua --test
|
||||
```
|
||||
|
||||
### Manual Setup
|
||||
```lua
|
||||
-- In your init.lua or plugin file
|
||||
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://your-gitea/tia-lsp.git", -- tree-sitter parser source
|
||||
cmp = true,
|
||||
workspace_types = true,
|
||||
auto_prefix = true,
|
||||
})
|
||||
```
|
||||
### Mason Installation (Neovim)
|
||||
|
||||
### Mason installation
|
||||
For Neovim users, install via [mason.nvim](https://github.com/mason-org/mason.nvim) using a custom registry. See the [`tia-lsp.nvim` README](https://gitea.l-tech.rs/lazar/tia-lsp.nvim) for full setup instructions.
|
||||
|
||||
`tia-lsp` can be installed via [mason.nvim](https://github.com/mason-org/mason.nvim) using a custom registry. The setup below uses a `file:` registry sourced from a Gitea-hosted `tia-mason-registry` repo (cloned by lazy.nvim), and falls back to the official mason registry for any other packages.
|
||||
|
||||
1. Clone the registry repo as a lazy.nvim plugin:
|
||||
```lua
|
||||
-- ~/.config/nvim/lua/plugins/tia-mason-registry.lua
|
||||
return {
|
||||
url = "https://your-gitea/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. Install `yq` (one-time prerequisite for mason's `file:` registry):
|
||||
```
|
||||
:MasonInstall yq
|
||||
```
|
||||
4. Install the server:
|
||||
```
|
||||
:MasonInstall tia-lsp
|
||||
```
|
||||
5. Verify: open a `.scl` file and run `:LspInfo` — `tia_lsp` should be attached, and `vim.fn.exepath("tia-lsp")` should resolve to `~/.local/share/nvim/mason/bin/tia-lsp`.
|
||||
|
||||
To upgrade: tag a new `vX.Y.Z` release on the `tia-lsp` Gitea repo, bump `source.id` in `tia-mason-registry/packages/tia-lsp/package.yaml`, push the registry repo, then `:MasonInstall tia-lsp` again.
|
||||
|
||||
## 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. Use `:SCLFormat` to format, then `:SCLCollapseAllAttrBlocks` to collapse while preserving the ability to expand later.
|
||||
Quick summary:
|
||||
1. Add the `tia-mason-registry` as a lazy.nvim plugin
|
||||
2. Register it with mason: `registries = { "file:~/.local/share/nvim/lazy/tia-mason-registry", "github:mason-org/mason-registry" }`
|
||||
3. `:MasonInstall tia-lsp`
|
||||
|
||||
## External UDT Support
|
||||
|
||||
@@ -232,24 +90,18 @@ The LSP automatically scans for SCL files in `data_types/` folder and extracts T
|
||||
|
||||
### Option 3: Generate `.plc.json`
|
||||
```bash
|
||||
lua ~/dev/tia-lsp/src/plc_json.lua --generate
|
||||
lua src/plc_json.lua --generate
|
||||
```
|
||||
|
||||
## 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.
|
||||
The server scans for `.db` files in the workspace and provides auto-completion for global data blocks and their members.
|
||||
|
||||
### How it works
|
||||
|
||||
1. **Workspace Scanning**: When opening a `.scl` file, the plugin scans the project for `.db` files
|
||||
1. **Workspace Scanning**: When opening a `.scl` file, the server scans the project for `.db` files
|
||||
2. **DB Parsing**: Parses `DATA_BLOCK` definitions and extracts members from `VAR` sections
|
||||
3. **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`
|
||||
3. **Auto-completion**: Provides completion for DB names and members
|
||||
|
||||
### Example
|
||||
|
||||
@@ -262,60 +114,61 @@ The plugin automatically scans for `.db` files in the workspace and provides aut
|
||||
#instParameterManager(hmiInterface:="HmiData".units, ...)
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
tia-lsp/
|
||||
├── README.md # This file
|
||||
├── package.json # NPM scripts (tree-sitter)
|
||||
├── Makefile # Build commands
|
||||
├── grammar.js # Tree-sitter grammar (SCL language)
|
||||
├── tree-sitter.json # Parser config
|
||||
├── queries/ # Tree-sitter queries
|
||||
│ └── scl/ # Per-language query dir (SCL)
|
||||
│ ├── highlights.scm # Syntax highlighting
|
||||
│ ├── indents.scm # Indentation
|
||||
│ ├── folds.scm # Code folding
|
||||
│ ├── locals.scm # Variable scoping
|
||||
│ └── tags.scm # Navigation tags
|
||||
├── src/ # LSP server
|
||||
│ ├── main.lua # Main entry point (JSON-RPC over stdio)
|
||||
│ ├── parser.lua # SCL parser (will become parser_scl.lua + dispatch)
|
||||
│ ├── treesitter.lua # Tree-sitter integration
|
||||
│ ├── json.lua # JSON encoder/decoder
|
||||
│ ├── plc_json.lua # External UDT loading (language-agnostic)
|
||||
│ ├── diagnostics.lua # Linter diagnostics
|
||||
│ └── formatter.lua # Document formatter
|
||||
└── lua/
|
||||
├── tia_lsp/ # Neovim plugin
|
||||
│ ├── init.lua # Main plugin setup
|
||||
│ └── plugins/
|
||||
│ └── scl.lua # LazyVim plugin spec (SCL filetype)
|
||||
└── tia/ # Language modules (shared across TIA languages)
|
||||
├── auto_prefix.lua
|
||||
├── attr_toggle.lua
|
||||
├── blink_cmp_source.lua
|
||||
├── builtin_instructions.lua
|
||||
├── db_parser.lua
|
||||
├── fb_parser.lua
|
||||
├── multiline_params.lua
|
||||
├── udt_parser.lua
|
||||
├── variables.lua
|
||||
└── workspace_types.lua
|
||||
```
|
||||
|
||||
## Building Tree-sitter Parser
|
||||
|
||||
```bash
|
||||
# Generate parser from grammar.js
|
||||
npm run build
|
||||
# or: tree-sitter generate
|
||||
tree-sitter generate
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
# or: tree-sitter test
|
||||
# Run parser tests
|
||||
tree-sitter test
|
||||
|
||||
# Parse a single SCL file
|
||||
tree-sitter parse <file.scl>
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
tia-lsp/
|
||||
├── src/ # LSP server (uses dofile)
|
||||
│ ├── main.lua # Entry point, JSON-RPC protocol
|
||||
│ ├── parser.lua # SCL parser (will become parser_scl.lua + dispatch)
|
||||
│ ├── diagnostics.lua # Linter (source = "tia_lsp")
|
||||
│ ├── formatter.lua # Document formatter
|
||||
│ ├── treesitter.lua # Tree-sitter integration
|
||||
│ ├── plc_json.lua # External UDT/DB loading (language-agnostic)
|
||||
│ ├── builtin_instructions.lua # TIA Portal built-in types
|
||||
│ ├── json.lua # JSON encoder/decoder
|
||||
│ ├── grammar.json # Generated tree-sitter grammar
|
||||
│ ├── node-types.json # Generated node types
|
||||
│ ├── parser.c # Generated tree-sitter parser
|
||||
│ └── tree_sitter/ # Tree-sitter C runtime headers
|
||||
├── grammar.js # Tree-sitter grammar (language name: 'scl')
|
||||
├── tree-sitter.json # Parser config
|
||||
├── package.json # NPM scripts (tree-sitter)
|
||||
├── Makefile # Build commands
|
||||
├── generate_plc_json.lua # .plc.json generator utility
|
||||
└── test/ # Server tests
|
||||
├── run_tests.lua
|
||||
├── test_harness.lua
|
||||
├── test_formatter.lua
|
||||
└── test_plc_json.lua
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
The server (`src/main.lua`) communicates via JSON-RPC over stdio and handles:
|
||||
- Text document synchronization
|
||||
- Diagnostics (linting)
|
||||
- Formatting
|
||||
- Completion, hover, go-to-definition
|
||||
- Semantic tokens
|
||||
- Inlay hints
|
||||
- Workspace symbols
|
||||
|
||||
The Neovim plugin (`tia-lsp.nvim`) manages the LSP client lifecycle, editor features, and workspace scanning. See its README for details.
|
||||
|
||||
## SCL Code Example
|
||||
|
||||
```pascal
|
||||
@@ -335,24 +188,24 @@ myVar.temperature := 25.5;
|
||||
END_FUNCTION_BLOCK
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
The plugin uses a standalone LSP server (`src/main.lua`) that communicates via JSON-RPC over stdio. The server handles:
|
||||
- Text document synchronization
|
||||
- Diagnostics (linting)
|
||||
- Formatting
|
||||
- Completion, hover, go-to-definition
|
||||
- Semantic tokens
|
||||
|
||||
The Neovim plugin (`lua/tia_lsp/init.lua`) manages:
|
||||
- LSP client lifecycle via `vim.lsp.start()`
|
||||
- FileType autocmd for lazy loading
|
||||
- blink.cmp integration
|
||||
- Workspace scanning for UDTs/DBs
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Neovim 0.11+** (uses `vim.lsp.start()`)
|
||||
- **nvim-treesitter** - Syntax highlighting
|
||||
- **blink.cmp** - Optional, for completion
|
||||
- **Lua 5.1+** - LSP server runtime
|
||||
- **Lua 5.1+** — LSP server runtime
|
||||
- **tree-sitter CLI** — For regenerating the parser from `grammar.js` (only needed during development)
|
||||
- **Node.js** — For tree-sitter CLI (only needed during development)
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Run server tests
|
||||
lua test/run_tests.lua
|
||||
|
||||
# Run individual test files
|
||||
lua test/test_formatter.lua
|
||||
lua test/test_plc_json.lua
|
||||
|
||||
# Run LSP server in test mode
|
||||
lua src/main.lua --test
|
||||
```
|
||||
|
||||
Tests use files from a reference project (override with `SCL_REF_PROJECT=/path/to/ref lua test/run_tests.lua`).
|
||||
|
||||
+2
-6
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
package.path = package.path .. ";lua/?.lua;src/?.lua"
|
||||
package.path = package.path .. ";src/?.lua"
|
||||
|
||||
local test = dofile("test/test_harness.lua")
|
||||
|
||||
print("========================================")
|
||||
print(" SCL LSP - Test Suite")
|
||||
print(" tia-lsp - Server Test Suite")
|
||||
print("========================================")
|
||||
print(string.format("Reference Project: %s", test.REF_PROJECT))
|
||||
|
||||
@@ -25,12 +25,8 @@ local function run_all_tests()
|
||||
end
|
||||
end
|
||||
|
||||
run_test_file("test_udt.lua")
|
||||
run_test_file("test_db.lua")
|
||||
run_test_file("test_fb.lua")
|
||||
run_test_file("test_formatter.lua")
|
||||
run_test_file("test_plc_json.lua")
|
||||
run_test_file("test_integration.lua")
|
||||
|
||||
test.report()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user