lsp: Use nvim_buf_get_lines in locations_to_items and add more tests (#12357)

* LSP: Add tests & use nvim_buf_get_lines in locations_to_items

This is to add support for cases where the server returns a URI in the
locations that does not have a file scheme but needs to be loaded via a
BufReadCmd event.

* LSP: Don't iterate through all lines in locations_to_items

* fixup! LSP: Don't iterate through all lines in locations_to_items

* fixup! fixup! LSP: Don't iterate through all lines in locations_to_items

* fixup! fixup! fixup! LSP: Don't iterate through all lines in locations_to_items
This commit is contained in:
Mathias Fußenegger 2020-06-30 17:48:04 +02:00 committed by GitHub
parent 1920ba4b55
commit 554b21261e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 26 deletions

View File

@ -1089,40 +1089,31 @@ function M.locations_to_items(locations)
for _, d in ipairs(locations) do
-- locations may be Location or LocationLink
local uri = d.uri or d.targetUri
local fname = assert(vim.uri_to_fname(uri))
local range = d.range or d.targetSelectionRange
table.insert(grouped[fname], {start = range.start})
table.insert(grouped[uri], {start = range.start})
end
local keys = vim.tbl_keys(grouped)
table.sort(keys)
-- TODO(ashkan) I wish we could do this lazily.
for _, fname in ipairs(keys) do
local rows = grouped[fname]
for _, uri in ipairs(keys) do
local rows = grouped[uri]
table.sort(rows, position_sort)
local i = 0
for line in io.lines(fname) do
for _, temp in ipairs(rows) do
local pos = temp.start
local row = pos.line
if i == row then
local col
if pos.character > #line then
col = #line
else
col = vim.str_byteindex(line, pos.character)
end
table.insert(items, {
filename = fname,
lnum = row + 1,
col = col + 1;
text = line;
})
end
end
i = i + 1
local bufnr = vim.uri_to_bufnr(uri)
vim.fn.bufload(bufnr)
local filename = vim.uri_to_fname(uri)
for _, temp in ipairs(rows) do
local pos = temp.start
local row = pos.line
local line = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1]
local col = M.character_offset(bufnr, row, pos.character)
table.insert(items, {
filename = filename,
lnum = row + 1,
col = col + 1;
text = line;
})
end
end
return items

View File

@ -1070,6 +1070,64 @@ describe('LSP', function()
]])
end)
end)
describe('lsp.util.locations_to_items', function()
it('Convert Location[] to items', function()
local expected = {
{
filename = 'fake/uri',
lnum = 1,
col = 3,
text = 'testing'
},
}
local actual = exec_lua [[
local bufnr = vim.uri_to_bufnr("file://fake/uri")
local lines = {"testing", "123"}
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
local locations = {
{
uri = 'file://fake/uri',
range = {
start = { line = 0, character = 2 },
['end'] = { line = 0, character = 3 },
}
},
}
return vim.lsp.util.locations_to_items(locations)
]]
eq(expected, actual)
end)
it('Convert LocationLink[] to items', function()
local expected = {
{
filename = 'fake/uri',
lnum = 1,
col = 3,
text = 'testing'
},
}
local actual = exec_lua [[
local bufnr = vim.uri_to_bufnr("file://fake/uri")
local lines = {"testing", "123"}
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
local locations = {
{
targetUri = vim.uri_from_bufnr(bufnr),
targetRange = {
start = { line = 0, character = 2 },
['end'] = { line = 0, character = 3 },
},
targetSelectionRange = {
start = { line = 0, character = 2 },
['end'] = { line = 0, character = 3 },
}
},
}
return vim.lsp.util.locations_to_items(locations)
]]
eq(expected, actual)
end)
end)
describe('lsp.util.symbols_to_items', function()
describe('convert DocumentSymbol[] to items', function()
it('DocumentSymbol has children', function()