diff --git a/AGENTS.md b/AGENTS.md index 9080c69..6317527 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -104,7 +104,7 @@ return M - No trailing whitespace ### Comments -**DO NOT ADD COMMENTS** in code unless explicitly requested by the user. +Add comments to explain non-obvious code sections, complex logic, and public API functions. Keep comments concise and relevant. ### Parser Module API All parser modules must implement: diff --git a/lua/scl/builtin_instructions.lua b/lua/scl/builtin_instructions.lua index 5059ef8..a9d9066 100644 --- a/lua/scl/builtin_instructions.lua +++ b/lua/scl/builtin_instructions.lua @@ -1,5 +1,9 @@ +-- TIA Portal built-in instructions for SCL Neovim plugin +-- Defines functions, function blocks, and their parameters for completion + local M = {} +-- Built-in functions (return values, no state) M.FUNCTIONS = { ADD = true, SUB = true, @@ -38,6 +42,7 @@ M.FUNCTIONS = { I_BCD = true, } +-- Built-in function blocks (have state, need instance) M.FUNCTION_BLOCKS = { TON = true, TOF = true, @@ -64,6 +69,8 @@ M.FUNCTION_BLOCKS = { DATALOG = true, } +-- Parameter definitions for built-in instructions +-- Format: { inputs = { { name, type }, ... }, outputs = { { name, type }, ... } } M.PARAMETERS = { TON = { inputs = { { name = "IN", type = "BOOL" }, { name = "PT", type = "TIME" } }, outputs = { { name = "Q", type = "BOOL" }, { name = "ET", type = "TIME" } } }, TOF = { inputs = { { name = "IN", type = "BOOL" }, { name = "PT", type = "TIME" } }, outputs = { { name = "Q", type = "BOOL" }, { name = "ET", type = "TIME" } } }, @@ -121,14 +128,23 @@ M.PARAMETERS = { I_BCD = { inputs = { { name = "IN" } }, outputs = { { name = "OUT" } } }, } +--- Get parameter info for a built-in instruction +--- @param name string The instruction name +--- @return table|nil Parameter definition with inputs and outputs arrays function M.get_parameters(name) return M.PARAMETERS[name:upper()] end +--- Check if name is a known function block +--- @param name string The name to check +--- @return boolean True if known function block function M.is_known_function_block(name) return M.FUNCTION_BLOCKS[name:upper()] or false end +--- Check if name is a known function +--- @param name string The name to check +--- @return boolean True if known function function M.is_known_function(name) return M.FUNCTIONS[name:upper()] or false end diff --git a/lua/scl/db_parser.lua b/lua/scl/db_parser.lua index cab480c..bc1116c 100644 --- a/lua/scl/db_parser.lua +++ b/lua/scl/db_parser.lua @@ -3,10 +3,30 @@ local M = {} +-- Cache for parsed DBs: { [db_name] = db_definition } local db_cache = {} +-- Inline DB definitions (from comments): { [db_name] = db_definition } local inline_dbs = {} +-- DB Definition structure: +-- { +-- name = "DBName", +-- title = "Data Block Title", +-- version = "0.1", +-- comment = "User comment", +-- members = { +-- { +-- name = "memberName", +-- type = "Bool" or '"OtherUdt"', +-- attributes = "{ S7_SetPoint := 'True' }", +-- comment = "Member comment", +-- is_udt = false -- true if type is a quoted UDT reference +-- } +-- } +-- } + +-- Register an inline DB definition (from comments or other sources) function M.register_inline_db(db) if db and db.name then inline_dbs[db.name] = db diff --git a/lua/scl/multiline_params.lua b/lua/scl/multiline_params.lua index 81e984a..7492093 100644 --- a/lua/scl/multiline_params.lua +++ b/lua/scl/multiline_params.lua @@ -1,5 +1,11 @@ +-- Multiline parameter filling for SCL function block calls +-- Automatically expands FB calls to multi-line format with all parameters + local M = {} +--- Get interface for built-in FB types (TON, TOF, etc.) +--- @param var_type string The FB type name +--- @return table|nil Interface with inputs, outputs, inouts local function get_builtin_interface(var_type) local builtin = require("scl.builtin_instructions") local clean_type = var_type:gsub('"', ''):gsub("#", ""):upper() @@ -14,6 +20,9 @@ local function get_builtin_interface(var_type) return nil end +--- Get interface for custom FB types from workspace +--- @param var_type string The FB type name +--- @return table|nil Interface with inputs, outputs, inouts local function get_fb_interface(var_type) local fb_parser = require("scl.fb_parser") local clean_type = var_type:gsub('"', '') @@ -26,6 +35,9 @@ local function get_fb_interface(var_type) return fb_parser.get_fb_interface(clean_type) end +--- Check if a type is a known FB type +--- @param var_type string The type name to check +--- @return boolean True if type is an FB local function is_fb_type(var_type) local fb_parser = require("scl.fb_parser") local clean_type = var_type:gsub('"', '') @@ -38,6 +50,9 @@ local function is_fb_type(var_type) return fb_parser.is_fb_type(clean_type) end +--- Get list of known local variable names +--- @param bufnr number Buffer number +--- @return table Set of variable names local function get_known_variables(bufnr) local scl_vars = require("scl.variables") local variables = scl_vars.extract_variables(bufnr) @@ -48,11 +63,17 @@ local function get_known_variables(bufnr) return known end +--- Get the type of a variable by name +--- @param var_name string Variable name +--- @param bufnr number Buffer number +--- @return string|nil Variable type, or nil if not found local function get_variable_type(var_name, bufnr) local scl_vars = require("scl.variables") return scl_vars.get_variable_type(var_name, bufnr) end +--- Fill multiline parameters for FB call at cursor +--- Expands single-line call to multi-line with all parameters function M.fill_multiline_params() local bufnr = vim.api.nvim_get_current_buf() local cursor = vim.api.nvim_win_get_cursor(0) @@ -169,6 +190,11 @@ function M.fill_multiline_params() vim.api.nvim_win_set_cursor(0, { new_cursor_row, new_cursor_col }) end +--- Check if cursor is inside an FB call parameter list +--- @param bufnr number Buffer number +--- @param cursor_row number Current row (1-based) +--- @param cursor_col number Current column (1-based) +--- @return boolean True if inside FB call params local function is_inside_fb_call(bufnr, cursor_row, cursor_col) local function get_line_text(rownum) return vim.api.nvim_buf_get_lines(bufnr, rownum - 1, rownum, false)[1] or "" @@ -214,6 +240,9 @@ local function is_inside_fb_call(bufnr, cursor_row, cursor_col) return false end +--- Jump to next parameter in FB call +--- Used for Tab navigation within parameter lists +--- @return boolean True if jumped to next param, false otherwise function M.jump_to_next_param() local cursor = vim.api.nvim_win_get_cursor(0) local row = cursor[1]