feat(lsp): add references provider for goto references

Add referencesProvider capability and handler to support LSP
references (gr keybinding in LazyVim). Searches all occurrences
of a symbol in the current document.
This commit is contained in:
2026-02-19 14:10:14 +01:00
parent e002e7f56d
commit cb0b24d47b
+62
View File
@@ -61,6 +61,7 @@ local capabilities = {
resolveProvider = false, resolveProvider = false,
}, },
definitionProvider = true, definitionProvider = true,
referencesProvider = true,
documentSymbolProvider = true, documentSymbolProvider = true,
diagnosticProvider = { relatedDocuments = {} }, diagnosticProvider = { relatedDocuments = {} },
textDocumentSync = 1, textDocumentSync = 1,
@@ -456,6 +457,67 @@ function handlers.textDocument_definition(params)
return nil return nil
end end
function handlers.textDocument_references(params)
local uri = params.textDocument.uri
local doc = documents[uri]
if not doc then
return nil
end
local lines = {}
for line in doc.content:gmatch("([^\n]*)\n") do
table.insert(lines, line)
end
if params.position.line + 1 > #lines then
return nil
end
local line = lines[params.position.line + 1]
local col = params.position.character + 1
local word_start = col
while word_start > 1 and line:sub(word_start - 1, word_start - 1):match("[%w_]") do
word_start = word_start - 1
end
local word_end = col
while word_end <= #line and line:sub(word_end, word_end):match("[%w_]") do
word_end = word_end + 1
end
local word = line:sub(word_start, word_end - 1):gsub("^#", "")
if not word or word == "" then
return nil
end
local references = {}
for line_num, line_content in ipairs(lines) do
local search_col = 1
while search_col <= #line_content do
local match_start, match_end = line_content:find("[%w_]+", search_col)
if not match_start then
break
end
local matched_word = line_content:sub(match_start, match_end)
if matched_word == word then
table.insert(references, {
uri = uri,
range = {
start = { line = line_num - 1, character = match_start - 1 },
["end"] = { line = line_num - 1, character = match_end },
},
})
end
search_col = match_end + 1
end
end
if #references > 0 then
return references
end
return nil
end
function handlers.textDocument_documentSymbol(params) function handlers.textDocument_documentSymbol(params)
local uri = params.textDocument.uri local uri = params.textDocument.uri
local doc = documents[uri] local doc = documents[uri]