VCI-exported .scl files use all-caps attribute names (EXTERNALACCESSIBLE,
EXTERNALVISIBLE, EXTERNALWRITABLE) which were not in the allowed list,
triggering spurious SCL005 warnings.
diagnostics.lua:
- Add VAR DB_SPECIFIC to section detection
- Make all VAR/END_VAR detection case-insensitive (matches grammar)
- Replace 20-line hardcoded type check list with builtin.is_known_data_type()
and builtin.is_known_type_or_instruction() — now uses the expanded
DATA_TYPES table from Phase 4 instead of inline string comparisons
- Add attribute validation: warn on unknown per-variable attributes
(SCL005). Valid attributes: ExternalWritable, ExternalVisible,
ExternalAccessible, S7_SetPoint, S7_Optimized_Access
- Allow optional semicolon after END_VAR
parser.lua:
- Add VAR DB_SPECIFIC to section detection and var_type classification
- Make all block detection case-insensitive (FUNCTION_BLOCK, FUNCTION,
ORGANIZATION_BLOCK, END_FUNCTION_BLOCK, etc.)
- Make TYPE/END_TYPE, STRUCT/END_STRUCT, VAR/END_VAR case-insensitive
- Fix VAR RETAIN vs VAR NON_RETAIN classification (NON_RETAIN was
matching the RETAIN branch first)
- Allow optional semicolon after END_VAR and END_STRUCT
formatter.lua:
- Add VAR DB_SPECIFIC and VAR_DB_SPECIFIC to BLOCKS and VAR_KEYWORDS
- Fix get_keyword() to handle multi-word VAR keywords (VAR NON_RETAIN,
VAR DB_SPECIFIC, VAR CONSTANT, VAR RETAIN) — normalizes spaces to
underscores so the keyword lookup succeeds
- Fix is_new_statement detection for space-form VAR keywords
All 38 formatter tests pass. Parser and diagnostics load without errors.
The semantic tokens delta calculation had a bug where previous delta lines
were used instead of absolute lines, causing cumulative errors that led
to 'Invalid line: out of range' in Neovim's semantic token renderer.
Since semantic tokens were already disabled (full=false, range=false) but
Neovim still attempted to process them, remove the capability entirely
so Neovim doesn't set up the semantic token decoration provider at all.
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)
Rename the project from scl_lsp to tia_lsp to future-proof for additional
TIA Portal languages (STL/AWL, LAD, FBD). The 'scl' language name is kept
as-is for the SCL filetype and tree-sitter parser; future languages get
their own names (stl, lad, fbd).
Project-wide changes:
- lua/scl_lsp/ → lua/tia_lsp/ (plugin entry point)
- lua/scl/ → lua/tia/ (language modules, shared across TIA langs)
- require('scl.*') → require('tia.*')
- require('scl_lsp') → require('tia_lsp')
- LSP client name: 'scl_lsp' → 'tia_lsp'
- Diagnostic source: 'scl_lsp' → 'tia_lsp' (src/diagnostics.lua)
- package.json name: 'scl-language-server' → 'tia-lsp'
lua/tia_lsp/init.lua:
- Add vim.fn.exepath('tia-lsp') detection so the plugin prefers the
mason-installed executable and falls back to { 'lua', server_path }
for manual installs.
- Add opts.ts_parser_url to configure the tree-sitter parser source.
- Remove hardcoded ~/dev/scl_lsp paths in favor of ~/dev/tia-lsp and
the new ts_parser_url option.
Cleanup:
- Delete lua/tia/init.lua (dead code, unreferenced duplicate of tia_lsp).
- Delete scl_lsp.sh (replaced by the mason-installed bin/tia-lsp wrapper).
- Update README.md and AGENTS.md to reflect the two-repo split
(tia-lsp server + tia-lsp.nvim plugin) and document Mason installation.
Unchanged (intentional):
- grammar.js, src/grammar.json, src/parser.c: tree-sitter language name
remains 'scl' (it's the language, not the project).
- Filetype patterns ('scl', 'udt', 'db') in autocmds.
- :SCL* command names (per-filetype prefix; future :STL* etc.).
Tests pass with the same pre-existing failures as before the rename
(formatter VAR_INPUT test, udt_parser line 199 const-variable bug,
plc_json reference-project-missing). No new failures introduced.
The formatter was incorrectly treating multi-line attribute blocks as
assignments, causing AUTHOR/VERSION lines to get weird indentation.
Lines like:
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
Were being processed incorrectly because the attribute block line
contains := but no semicolon, causing the formatter to treat the
next line as a continuation.
Fix by tracking in_attr_block state and skipping assignment detection
for lines inside or exiting attribute blocks.
- SCLFormat: Remove clear_buffer_state() call that was preventing
expand after formatting (attr_toggle state now preserved)
- Diagnostics: Fix false 'Undefined variable' for IEC literals
like T#2s, D#1d, S5T#1s (TIME, DATE, S5TIME types)
- Formatter: Fix block comments (* ... *) being misidentified as
FB calls in VAR_IN_OUT/VAR_INPUT/VAR_OUTPUT sections
- Formatter: Fix array-based FB calls like instTimers[idx].TON()
not being properly formatted with aligned parameters
- Update AGENTS.md to encourage comments instead of forbidding them
- Add docstrings to all public functions in src/ modules
- Add module headers and function comments to lua/scl/ modules
- Fix formatter to properly indent multi-line IF/ELSIF conditions
- Fix FB call detection to not match IF statements with parentheses
- Add in_condition state to track when inside IF/ELSIF condition (before THEN)
- Use condition_indent for continuation lines in conditions
- Fixes multiline IF/ELSIF conditions being incorrectly indented
- Add comprehensive formatter test suite with 38 tests
- Test multiline assignments, FB calls, control structures
- Test IF, FOR, WHILE, CASE, REPEAT statements
- Test regions, structs, var sections
- Update AGENTS.md with formatter test command
- Fix formatter to properly detect when multiline assignment ends
- Add check for line ending with := and ; before checking continuation
- Fixes issue where subsequent lines were incorrectly indented
- Fix formatter to detect continuation lines that don't start with
operators (e.g., #variable AND ... continuation lines)
- All continuation lines now align vertically after :=
- Format multi-line assignments with proper alignment
- Format FB calls in multiline style with parameter alignment
- Auto-expand collapsed attribute blocks before save
- Rename command from LspSCLFormat to SCLFormat
- Condense AGENTS.md and add testing section with reference project
- Skip // line comments when finding type separator colon
- Only match : that is NOT followed by = (avoid := assignment)
- Remove line comments from type_part before extraction
- Fixes false 'Unknown data type' warnings in VAR sections
- Add pattern matching for quoted type names like "MyUDT"
- Handle quoted types in ARRAY ... OF declarations
- Skip empty base_type to avoid spurious warnings
- Fix UDT TYPE parsing: don't clear pending_type_name on VERSION/TITLE lines
- Fix UDT field type extraction: handle attribute blocks before colon
- Add comment capture for UDT type definitions
- Add better error messages when member resolution fails
- Handle quoted type names in field declarations
- Fix chain detection to properly extract #var and member path
- Check all type sources (doc.types, external_types, builtins) for resolution
- Return helpful error messages when type resolution fails
- Prevent fallthrough to type check when member access is detected
- Show which type couldn't be found in resolution chain
- Add member access chain resolution in hover handler
- Parse #var.member.submember notation and resolve type chain
- Show member comments in hover tooltip
- Extract comments from UDT and DB file fields
- Combine all type sources (doc.types, external_types, builtin)
- Add type_definition rule for UDT files (TYPE/STRUCT/END_STRUCT/END_TYPE)
- Add data_block rule for DB files (DATA_BLOCK/BEGIN/END_DATA_BLOCK)
- Add NON_RETAIN and RETAIN modifiers support in data blocks
- Keywords now highlighted correctly in .udt and .db files
- extract_variables: Parse STRUCT fields in TYPE sections for .udt files
- extract_types: Handle quoted type names and multiple type definitions
- declaration handler: Extract quoted type names for goto declaration
- Add filetype detection for .udt and .db files in nvim config
Add referencesProvider capability and handler to support LSP
references (gr keybinding in LazyVim). Searches all occurrences
of a symbol in the current document.
The semantic tokens were causing 'Invalid line: out of range' errors
when opening certain files. This appears to be related to the delta
mode not being properly handled. Disabled semantic tokens for now
to prevent the errors.
- Wrap token generation in pcall to catch any errors
- Add validation for all token parameters (line, startChar, length)
- Validate deltaStart is non-negative
- Return empty tokens if any error occurs
- This should prevent the 'Invalid line: out of range' errors
The error 'Invalid line: out of range' was caused by semantic tokens
and inlay hints using variable line numbers that might be out of bounds
for the current document content. This could happen when the cached
variables from a previous document version have line numbers that don't
match the current content.
Added validation to both textDocument_semanticTokensFull and
textDocument_inlayHint to ensure line numbers are within the valid
range (0 to total_lines - 1) before processing.
When the formatter automatically collapses attribute blocks, the
original content is lost and cannot be restored by the toggle
module. This broke the attribute expand/collapse functionality.
Changed default from collapseAttributes = true to false.
Users who want collapsing should:
1. Use :LspSCLFormat to format (preserves original content)
2. Then use :SCLCollapseAllAttrBlocks to collapse (stores original)
3. Now toggle/expand works correctly because content is stored
The get_keyword() function was using pattern ^(%w+_%w+) which only
matched up to the second underscore, causing VAR_IN_OUT to be
extracted as VAR_IN. Since VAR_IN is not in VAR_KEYWORDS, the
VAR_IN_OUT block was not being pushed onto the stack.
Fixed by changing the pattern to ^([%w_]+) to capture the entire
keyword including all underscores.
This ensures variables inside VAR_IN_OUT, VAR_CONSTANT, and other
multi-underscore VAR sections are properly indented.
The parser was incorrectly finding the ':' inside attribute blocks like
{EXTERNALACCESSIBLE := 'false'} instead of the ':' after them.
Added 'break' after finding the first ':' outside braces to ensure
we get the correct type separator.
Fixes issue where variables like:
STARTING_BASEPOS : Int := 30;
were showing data_type as '= 30' instead of 'Int'.
Add documentation for new attribute block toggle feature including:
- New commands: SCLToggleAttrBlock, SCLExpandAllAttrBlocks, SCLCollapseAllAttrBlocks
- New keybindings: <Leader>xa, <Leader>xae, <Leader>xac
- Feature description and usage example
- Multi-line IF conditions: continuation lines at +1 from IF
- END_IF now decreases indent (reverted previous wrong change)
- Track multi-line condition state separately from THEN tracking
- Now matches TIA Portal expected format
- Track when IF has THEN on separate line
- Don't increase indent after IF until THEN is seen
- Increase indent after THEN for content
- Continuation lines in conditions stay at same level as IF
- END_IF stays at same level as content (TIA Portal style)
Per TIA Portal standard, END_IF stays at the same indent level as the
code inside the IF block, rather than decreasing. This matches the
reference file Em101Sequence.scl where nested END_IF statements are
properly aligned.
- Track first line of FB call separately with fb_call_first_line flag
- First line of FB call uses normal indent
- Continuation lines use continuation indent (base + fb_name_length + 2)
- Closing line uses normal indent
- Parameters now align correctly
- Use correct continuation indent formula (base + fb_name_length + 2)
- Fix closing line of FB call to use continuation indent
- Parameters on continuation lines are now aligned
- Re-indent comments to match current block level
- Add FB/function call continuation detection and alignment
- Support both #fbname and "FBName" syntax
- Fix FB call detection to exclude assignment statements
- Continuation lines get +1 indent level
- Default to tabs (not spaces) per TIA Portal standard
- Fix block keyword handling (IF, FOR, WHILE, CASE, REGION, etc.)
- Handle VAR section indentation (variables indented inside VAR)
- Fix IF/ELSIF/ELSE indentation (ELSIF/ELSE at same level as IF)
- Handle CASE labels and nested CASE statements
- Add missing semicolons after END_IF, END_FOR, END_CASE Handle block, etc.
- enders (END_IF, END_REGION, etc.) correctly
- Support compound keywords (END_IF, END_FUNCTION_BLOCK, etc.)
- Add db_parser.lua to parse .db files (DATA_BLOCK with VAR sections)
- Update workspace_types.lua to scan for .db files in project
- Update blink_cmp_source.lua to provide DB auto-completion:
- DB names available in general completion (without quotes)
- Type quote to get DB members
- Multi-level nested member access support
- Add DB count to workspace commands
- Update README with Global DB documentation