- Fix FB/function call parameter detection to prevent incorrect # prefixing - Preserve # prefix when filling multiline params - Add comma after first parameter and closing bracket on last param line - Fix Tab navigation to position cursor after :=/=> operators - Clean up dead code in multiline_params.lua - Add setup functions for multiline params feature in both scl and scl_lsp
201 lines
5.4 KiB
Lua
201 lines
5.4 KiB
Lua
local M = {}
|
|
|
|
local function get_fb_interface(var_type)
|
|
local fb_parser = require("scl.fb_parser")
|
|
local clean_type = var_type:gsub('"', '')
|
|
|
|
if fb_parser.get_cache_count() == 0 then
|
|
local ws = require("scl.workspace_types")
|
|
ws.scan_project_fbs(vim.api.nvim_get_current_buf())
|
|
end
|
|
|
|
return fb_parser.get_fb_interface(clean_type)
|
|
end
|
|
|
|
local function is_fb_type(var_type)
|
|
local fb_parser = require("scl.fb_parser")
|
|
local clean_type = var_type:gsub('"', '')
|
|
|
|
if fb_parser.get_cache_count() == 0 then
|
|
local ws = require("scl.workspace_types")
|
|
ws.scan_project_fbs(vim.api.nvim_get_current_buf())
|
|
end
|
|
|
|
return fb_parser.is_fb_type(clean_type)
|
|
end
|
|
|
|
local function get_known_variables(bufnr)
|
|
local scl_vars = require("scl.variables")
|
|
local variables = scl_vars.extract_variables(bufnr)
|
|
local known = {}
|
|
for _, v in ipairs(variables) do
|
|
known[v.name] = true
|
|
end
|
|
return known
|
|
end
|
|
|
|
local function get_variable_type(var_name, bufnr)
|
|
local scl_vars = require("scl.variables")
|
|
return scl_vars.get_variable_type(var_name, bufnr)
|
|
end
|
|
|
|
function M.fill_multiline_params()
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
local row = cursor[1]
|
|
local col = cursor[2]
|
|
|
|
local line = vim.api.nvim_get_current_line()
|
|
local line_before_cursor = line:sub(1, col)
|
|
|
|
local known_vars = get_known_variables(bufnr)
|
|
|
|
local fb_name = nil
|
|
local fb_prefix = ""
|
|
|
|
local prefix, var_name = line_before_cursor:match("(#?)([%w_]+)%s*%(%s*$")
|
|
if var_name and known_vars[var_name] then
|
|
fb_prefix = prefix or ""
|
|
fb_name = var_name
|
|
end
|
|
|
|
if not fb_name then
|
|
prefix, var_name = line_before_cursor:match("(#?)([%w_]+)%s*%([^)]-,%s*$")
|
|
if var_name and known_vars[var_name] then
|
|
fb_prefix = prefix or ""
|
|
fb_name = var_name
|
|
end
|
|
end
|
|
|
|
if not fb_name then
|
|
vim.notify("No FB instance found before cursor", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
local var_type = get_variable_type(fb_name, bufnr)
|
|
if not var_type then
|
|
vim.notify("Cannot find type for: " .. fb_name, vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
local clean_type = var_type:gsub('"', '')
|
|
if not is_fb_type(clean_type) then
|
|
vim.notify(clean_type .. " is not an FB/Function type", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
local fb_interface = get_fb_interface(clean_type)
|
|
if not fb_interface then
|
|
vim.notify("Cannot get interface for: " .. clean_type, vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
local params = {}
|
|
for _, inp in ipairs(fb_interface.inputs or {}) do
|
|
table.insert(params, inp.name .. " := ")
|
|
end
|
|
for _, inout in ipairs(fb_interface.inouts or {}) do
|
|
table.insert(params, inout.name .. " := ")
|
|
end
|
|
for _, out in ipairs(fb_interface.outputs or {}) do
|
|
table.insert(params, out.name .. " => ")
|
|
end
|
|
|
|
if #params == 0 then
|
|
vim.notify("No parameters found for: " .. clean_type, vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
local indent = line:match("^%s*") or ""
|
|
|
|
local continuation_indent = indent .. string.rep(" ", #fb_name + 2)
|
|
|
|
local lines_to_insert = {}
|
|
|
|
local first_line = indent .. fb_prefix .. fb_name .. "(" .. params[1] .. ","
|
|
table.insert(lines_to_insert, first_line)
|
|
|
|
for i = 2, #params do
|
|
local p = params[i]
|
|
local closing = (i == #params) and ");" or ","
|
|
local line_content = continuation_indent .. p .. closing
|
|
table.insert(lines_to_insert, line_content)
|
|
end
|
|
|
|
vim.api.nvim_buf_set_lines(bufnr, row - 1, row, false, lines_to_insert)
|
|
|
|
local new_cursor_row = row
|
|
local new_cursor_col = #indent + #fb_prefix + #fb_name + 1 + #params[1]
|
|
|
|
vim.api.nvim_win_set_cursor(0, { new_cursor_row, new_cursor_col })
|
|
end
|
|
|
|
function M.jump_to_next_param()
|
|
local cursor = vim.api.nvim_win_get_cursor(0)
|
|
local row = cursor[1]
|
|
local col = cursor[2]
|
|
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
local total_lines = vim.api.nvim_buf_line_count(bufnr)
|
|
|
|
local function get_line_text(rownum)
|
|
return vim.api.nvim_buf_get_lines(bufnr, rownum - 1, rownum, false)[1] or ""
|
|
end
|
|
|
|
local function find_next_param_on_line(start_row)
|
|
for i = start_row, total_lines do
|
|
local line = get_line_text(i)
|
|
local param_match = line:match("[%w_]+%s*:=") or line:match("[%w_]+%s*=>")
|
|
if param_match then
|
|
local op_end = line:find(":=") or line:find("=>")
|
|
vim.api.nvim_win_set_cursor(0, { i, op_end + 2 })
|
|
return true
|
|
end
|
|
if line:match("%)") then
|
|
break
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local current_line = get_line_text(row)
|
|
local text_after_cursor = current_line:sub(col + 1)
|
|
|
|
local next_param = text_after_cursor:match("([%w_]+)%s*:=") or text_after_cursor:match("([%w_]+)%s*=>")
|
|
if next_param then
|
|
local op_end = text_after_cursor:find(":=") or text_after_cursor:find("=>")
|
|
local new_col = col + op_end + 2
|
|
vim.api.nvim_win_set_cursor(0, { row, new_col })
|
|
return true
|
|
end
|
|
|
|
if not find_next_param_on_line(row + 1) then
|
|
local all_params = {}
|
|
local all_text = ""
|
|
for i = row, total_lines do
|
|
local l = get_line_text(i)
|
|
all_text = all_text .. l .. "\n"
|
|
if l:match("%)") then
|
|
break
|
|
end
|
|
end
|
|
for param in all_text:gmatch("([%w_]+)%s*:=") do
|
|
table.insert(all_params, param)
|
|
end
|
|
for param in all_text:gmatch("([%w_]+)%s*=>") do
|
|
table.insert(all_params, param)
|
|
end
|
|
|
|
if #all_params > 0 then
|
|
vim.api.nvim_feedkeys("> ", "m", false)
|
|
return true
|
|
end
|
|
else
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
return M
|