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:
+32
-16
@@ -296,7 +296,7 @@ function handlers.textDocument_hover(params)
|
||||
contents = { kind = "markdown", value = detail },
|
||||
range = {
|
||||
start = { line = params.position.line, character = word_start - 1 },
|
||||
endPos = { line = params.position.line, character = word_end - 1 },
|
||||
["end"] = { line = params.position.line, character = word_end - 1 },
|
||||
},
|
||||
}
|
||||
end
|
||||
@@ -315,7 +315,7 @@ function handlers.textDocument_hover(params)
|
||||
contents = { kind = "markdown", value = detail },
|
||||
range = {
|
||||
start = { line = params.position.line, character = word_start - 1 },
|
||||
endPos = { line = params.position.line, character = word_end - 1 },
|
||||
["end"] = { line = params.position.line, character = word_end - 1 },
|
||||
},
|
||||
}
|
||||
end
|
||||
@@ -449,7 +449,7 @@ function handlers.textDocument_definition(params)
|
||||
uri = uri,
|
||||
range = {
|
||||
start = { line = pos.line, character = pos.character },
|
||||
endPos = { line = pos.line, character = pos.character + #word },
|
||||
["end"] = { line = pos.line, character = pos.character + #word },
|
||||
},
|
||||
}
|
||||
end
|
||||
@@ -478,10 +478,10 @@ function handlers.textDocument_documentSymbol(params)
|
||||
table.insert(symbols, {
|
||||
name = func.kind:upper() .. " " .. func.name,
|
||||
kind = kind_map[func.kind] or 14,
|
||||
range = { start = { line = func.start, character = 0 }, endPos = { line = func.final, character = 0 } },
|
||||
range = { start = { line = func.start, character = 0 }, ["end"] = { line = func.final, character = 0 } },
|
||||
selectionRange = {
|
||||
start = { line = func.start, character = 0 },
|
||||
endPos = { line = func.start, character = #func.name },
|
||||
["end"] = { line = func.start, character = #func.name },
|
||||
},
|
||||
containerName = nil,
|
||||
})
|
||||
@@ -500,11 +500,11 @@ function handlers.textDocument_documentSymbol(params)
|
||||
detail = var_info.type or "VAR",
|
||||
range = {
|
||||
start = { line = var_info.line, character = 0 },
|
||||
endPos = { line = var_info.line, character = #var_name },
|
||||
["end"] = { line = var_info.line, character = #var_name },
|
||||
},
|
||||
selectionRange = {
|
||||
start = { line = var_info.line, character = var_info.character },
|
||||
endPos = { line = var_info.line, character = var_info.character + #var_name },
|
||||
["end"] = { line = var_info.line, character = var_info.character + #var_name },
|
||||
},
|
||||
containerName = nil,
|
||||
})
|
||||
@@ -526,11 +526,11 @@ function handlers.textDocument_documentSymbol(params)
|
||||
detail = detail,
|
||||
range = {
|
||||
start = { line = type_info.start_line or 0, character = 0 },
|
||||
endPos = { line = type_info.start_line or 0, character = #type_name },
|
||||
["end"] = { line = type_info.start_line or 0, character = #type_name },
|
||||
},
|
||||
selectionRange = {
|
||||
start = { line = type_info.start_line or 0, character = 0 },
|
||||
endPos = { line = type_info.start_line or 0, character = #type_name },
|
||||
["end"] = { line = type_info.start_line or 0, character = #type_name },
|
||||
},
|
||||
containerName = nil,
|
||||
})
|
||||
@@ -656,6 +656,10 @@ function handlers.textDocument_semanticTokensRange(params)
|
||||
return handlers.textDocument_semanticTokensFull(params)
|
||||
end
|
||||
|
||||
-- Aliases for method names with slashes converted to underscores
|
||||
handlers["textDocument_semanticTokens_full"] = handlers.textDocument_semanticTokensFull
|
||||
handlers["textDocument_semanticTokens_range"] = handlers.textDocument_semanticTokensRange
|
||||
|
||||
function handlers.textDocument_inlayHint(params)
|
||||
local uri = params.textDocument.uri
|
||||
local doc = documents[uri]
|
||||
@@ -708,7 +712,7 @@ function handlers.workspace_symbol(params)
|
||||
uri = uri,
|
||||
range = {
|
||||
start = { line = line, character = col },
|
||||
endPos = { line = line, character = col + length },
|
||||
["end"] = { line = line, character = col + length },
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -848,17 +852,26 @@ local function handle_message(message)
|
||||
if message.method == "$/cancelRequest" then
|
||||
return nil
|
||||
end
|
||||
local handler = handlers[message.method]
|
||||
-- Convert method name from "textDocument/didOpen" to "textDocument_didOpen"
|
||||
local method_name = message.method:gsub("/", "_")
|
||||
local handler = handlers[method_name]
|
||||
if handler then
|
||||
local ok, result = pcall(handler, message.params)
|
||||
if ok then
|
||||
return { id = message.id, result = result }
|
||||
else
|
||||
return { id = message.id, error = { code = -32603, message = tostring(result) } }
|
||||
-- Only return response for requests (have id), not notifications
|
||||
if message.id then
|
||||
if ok then
|
||||
return { id = message.id, result = result }
|
||||
else
|
||||
return { id = message.id, error = { code = -32603, message = tostring(result) } }
|
||||
end
|
||||
end
|
||||
else
|
||||
return { id = message.id, error = { code = -32601, message = "Method not found: " .. message.method } }
|
||||
-- Only return error for requests (have id)
|
||||
if message.id then
|
||||
return { id = message.id, error = { code = -32601, message = "Method not found: " .. message.method } }
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function main()
|
||||
@@ -871,6 +884,9 @@ local function main()
|
||||
if not line then
|
||||
break
|
||||
end
|
||||
-- Strip trailing \r (Windows line endings)
|
||||
line = line:gsub("\r$", "")
|
||||
|
||||
if line:match("^Content%-Length:%s*(%d+)") then
|
||||
content_length = tonumber(line:match("^Content%-Length:%s*(%d+)"))
|
||||
elseif line == "" then
|
||||
|
||||
Reference in New Issue
Block a user