Inintal commit
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
local M = {}
|
||||
|
||||
local function setup_package_path()
|
||||
local plugin_path = debug.getinfo(1, "S").source:gsub("^@", ""):match("(.*/)") or ""
|
||||
plugin_path = plugin_path:gsub("/lua/scl_lsp", "")
|
||||
local lua_path = plugin_path .. "/lua"
|
||||
if not package.path:match(lua_path) then
|
||||
package.path = lua_path .. "/?.lua;" .. package.path
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup(opts)
|
||||
setup_package_path()
|
||||
opts = opts or {}
|
||||
|
||||
local lspconfig_avail, lspconfig = pcall(require, "lspconfig")
|
||||
if not lspconfig_avail then
|
||||
vim.notify("lspconfig not found. Please install nvim-lspconfig.", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local server_path = opts.server_path or vim.fn.expand("~/dev/scl_lsp/src/main.lua")
|
||||
|
||||
local root_patterns = { ".git", "data_types", "plc.data.json" }
|
||||
local function get_root_dir(fname)
|
||||
local root = vim.fs.root(fname, root_patterns)
|
||||
return root or vim.fn.fnamemodify(fname, ":h")
|
||||
end
|
||||
|
||||
local function on_attach(client, bufnr)
|
||||
if opts.lsp and opts.lsp.on_attach then
|
||||
opts.lsp.on_attach(client, bufnr)
|
||||
end
|
||||
|
||||
if opts.lsp.formatting then
|
||||
vim.api.nvim_buf_create_user_command(bufnr, "LspSCLFormat", function()
|
||||
vim.lsp.buf.format({ name = "scl-language-server" })
|
||||
end, {})
|
||||
end
|
||||
end
|
||||
|
||||
lspconfig.scl_lsp = {
|
||||
default_config = {
|
||||
name = "scl-language-server",
|
||||
cmd = { "lua", server_path },
|
||||
filetypes = { "scl" },
|
||||
root_dir = get_root_dir,
|
||||
settings = {},
|
||||
on_attach = on_attach,
|
||||
},
|
||||
docs = {
|
||||
description = "Language server for Siemens SCL (LSP, Linter, Formatter)",
|
||||
default_config = {
|
||||
name = "scl-language-server",
|
||||
cmd = { "lua", server_path },
|
||||
filetypes = { "scl" },
|
||||
root_dir = "root_pattern('.git', 'data_types', 'plc.data.json')",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
M.setup_syntax(opts)
|
||||
M.create_commands()
|
||||
|
||||
if opts.auto_prefix ~= false then
|
||||
M.setup_auto_prefix()
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup_syntax(opts)
|
||||
local has_ts, ts = pcall(require, "nvim-treesitter.parsers")
|
||||
if has_ts and ts.get_parser_configs then
|
||||
local ok, parser_config = pcall(ts.get_parser_configs)
|
||||
if ok and parser_config then
|
||||
parser_config.scl = {
|
||||
install_info = {
|
||||
url = "file://" .. vim.fn.expand("~/dev/scl_lsp"),
|
||||
files = { "src/parser.c" },
|
||||
generate_requires_npm = false,
|
||||
requires_generate_from_grammar = false,
|
||||
},
|
||||
filetype = "scl",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if opts.cmp then
|
||||
local function try_register()
|
||||
local cmp_ok, cmp = pcall(require, "blink.cmp")
|
||||
local blink_source_ok, blink_source = pcall(require, "scl.blink_cmp_source")
|
||||
if cmp_ok and cmp and cmp.add_source_provider and blink_source_ok then
|
||||
local source_config = {
|
||||
name = "scl",
|
||||
provider = blink_source,
|
||||
score_offset = 100,
|
||||
}
|
||||
pcall(cmp.add_source_provider, "scl", source_config)
|
||||
pcall(cmp.add_filetype_source, "scl", "scl")
|
||||
|
||||
vim.notify("SCL: blink.cmp source registered", vim.log.levels.INFO)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if not try_register() then
|
||||
vim.api.nvim_create_autocmd("BufEnter", {
|
||||
pattern = "*.scl",
|
||||
once = true,
|
||||
callback = try_register,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if opts.workspace_types ~= false then
|
||||
local ok, workspace_types = pcall(require, "scl.workspace_types")
|
||||
if ok then
|
||||
workspace_types.setup({
|
||||
project_root = opts.project_root,
|
||||
library_paths = opts.library_paths,
|
||||
debug = opts.debug,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup_auto_prefix()
|
||||
local ok, auto_prefix = pcall(require, "scl.auto_prefix")
|
||||
if ok then
|
||||
auto_prefix.setup()
|
||||
end
|
||||
end
|
||||
|
||||
function M.prefix_current_word()
|
||||
local ok, auto_prefix = pcall(require, "scl.auto_prefix")
|
||||
if ok then
|
||||
auto_prefix.prefix_word()
|
||||
end
|
||||
end
|
||||
|
||||
function M.show_variables()
|
||||
local ok, variables = pcall(require, "scl.variables")
|
||||
if not ok then
|
||||
vim.notify("SCL variables module not found", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
local vars = variables.extract_variables()
|
||||
if #vars == 0 then
|
||||
vim.notify("No local variables found", vim.log.levels.INFO)
|
||||
return
|
||||
end
|
||||
|
||||
local lines = { "Local Variables:", "---" }
|
||||
for _, var in ipairs(vars) do
|
||||
local type_info = var.type and (" : " .. var.type) or ""
|
||||
table.insert(lines, "#" .. var.name .. type_info)
|
||||
end
|
||||
vim.notify(table.concat(lines, "\n"), vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
function M.show_workspace_types()
|
||||
local ok_ws, ws = pcall(require, "scl.workspace_types")
|
||||
local ok_udt, udt = pcall(require, "scl.udt_parser")
|
||||
local ok_fb, fb = pcall(require, "scl.fb_parser")
|
||||
|
||||
if not ok_ws or not ok_udt or not ok_fb then
|
||||
vim.notify("SCL workspace modules not found", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
local root = ws.get_project_root()
|
||||
local udt_names = udt.get_all_udt_names()
|
||||
local fb_names = fb.get_all_fb_names()
|
||||
|
||||
if not root then
|
||||
vim.notify("No project root detected", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
vim.notify("Project: " .. root .. "\nUDTs: " .. #udt_names .. "\nFBs/Functions: " .. #fb_names, vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
function M.rescan_workspace_types()
|
||||
local ok_ws, ws = pcall(require, "scl.workspace_types")
|
||||
local ok_udt, udt = pcall(require, "scl.udt_parser")
|
||||
local ok_fb, fb = pcall(require, "scl.fb_parser")
|
||||
|
||||
if not ok_ws or not ok_udt or not ok_fb then
|
||||
vim.notify("SCL workspace modules not found", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
udt.clear_cache()
|
||||
fb.clear_cache()
|
||||
ws.clear_root_cache()
|
||||
|
||||
local udt_result = ws.scan_project_udts()
|
||||
local fb_result = ws.scan_project_fbs()
|
||||
|
||||
vim.notify("Scanned UDTs: " .. udt_result.parsed_count .. "/" .. udt_result.total_files ..
|
||||
", FBs: " .. fb_result.parsed_count .. "/" .. fb_result.total_files, vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
function M.create_commands()
|
||||
vim.api.nvim_create_user_command("SCLShowVariables", function() M.show_variables() end, {})
|
||||
vim.api.nvim_create_user_command("SCLShowWorkspaceTypes", function() M.show_workspace_types() end, {})
|
||||
vim.api.nvim_create_user_command("SCLRescanWorkspaceTypes", function() M.rescan_workspace_types() end, {})
|
||||
vim.api.nvim_create_user_command("SCLPrefixWord", function() M.prefix_current_word() end, {})
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user