fix(lsp): Fix LSP server attachment and JSON parsing issues

- Replace lspconfig.scl_lsp registration with vim.lsp.start() + FileType autocmd
  for Neovim 0.11+ compatibility
- Fix Lua reserved keyword 'end' in tables (use bracket notation ['end'])
- Fix JSON decoder pattern matching bugs (s:find -> s:sub:match)
- Add LSP method name conversion (textDocument/didOpen -> textDocument_didOpen)
- Handle request vs notification correctly (only respond to requests with id)
- Strip CRLF line endings for Windows compatibility
- Add semantic token handler aliases
- Update documentation with implementation notes
This commit is contained in:
2026-02-18 13:03:14 +01:00
parent b5d50384fb
commit 246fa85442
3 changed files with 105 additions and 44 deletions
+45 -42
View File
@@ -13,51 +13,54 @@ 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",
local function start_lsp(bufnr)
local fname = vim.api.nvim_buf_get_name(bufnr)
if fname == "" then return end
local root_dir = vim.fs.root(fname, root_patterns)
or vim.fn.fnamemodify(fname, ":p:h")
vim.lsp.start({
name = "scl_lsp",
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')",
},
},
}
root_dir = root_dir,
on_attach = function(client, b)
if opts.lsp and opts.lsp.on_attach then
opts.lsp.on_attach(client, b)
end
if opts.lsp and opts.lsp.formatting then
vim.api.nvim_buf_create_user_command(b, "LspSCLFormat", function()
vim.lsp.buf.format({ name = "scl_lsp" })
end, {})
end
end,
})
end
-- Create FileType autocmd for future buffers
vim.api.nvim_create_autocmd("FileType", {
pattern = "scl",
callback = function(args)
start_lsp(args.buf)
end,
})
-- Create global format command (works on current buffer)
vim.api.nvim_create_user_command("LspSCLFormat", function()
vim.lsp.buf.format({ name = "scl_lsp" })
end, {})
-- Start LSP for any existing scl buffers (handles lazy loading case)
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
if vim.bo[bufnr].filetype == "scl" and vim.api.nvim_buf_is_loaded(bufnr) then
start_lsp(bufnr)
end
end
M.setup_syntax(opts)
M.setup_multiline_params()