mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #15017 from donbex/local-file-uri
fix(lsp): accept file URIs without a hostname
This commit is contained in:
commit
19a2e59f7e
@ -52,7 +52,7 @@ end
|
|||||||
|
|
||||||
--@private
|
--@private
|
||||||
local function is_windows_file_uri(uri)
|
local function is_windows_file_uri(uri)
|
||||||
return uri:match('^file:///[a-zA-Z]:') ~= nil
|
return uri:match('^file:/+[a-zA-Z]:') ~= nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a URI from a file path.
|
--- Get a URI from a file path.
|
||||||
@ -74,7 +74,7 @@ local function uri_from_fname(path)
|
|||||||
return table.concat(uri_parts)
|
return table.concat(uri_parts)
|
||||||
end
|
end
|
||||||
|
|
||||||
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*)://.*'
|
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*):.*'
|
||||||
|
|
||||||
--- Get a URI from a bufnr
|
--- Get a URI from a bufnr
|
||||||
--@param bufnr (number): Buffer number
|
--@param bufnr (number): Buffer number
|
||||||
@ -100,10 +100,10 @@ local function uri_to_fname(uri)
|
|||||||
uri = uri_decode(uri)
|
uri = uri_decode(uri)
|
||||||
-- TODO improve this.
|
-- TODO improve this.
|
||||||
if is_windows_file_uri(uri) then
|
if is_windows_file_uri(uri) then
|
||||||
uri = uri:gsub('^file:///', '')
|
uri = uri:gsub('^file:/+', '')
|
||||||
uri = uri:gsub('/', '\\')
|
uri = uri:gsub('/', '\\')
|
||||||
else
|
else
|
||||||
uri = uri:gsub('^file://', '')
|
uri = uri:gsub('^file:/+', '/')
|
||||||
end
|
end
|
||||||
return uri
|
return uri
|
||||||
end
|
end
|
||||||
|
@ -53,12 +53,18 @@ describe('URI methods', function()
|
|||||||
|
|
||||||
describe('uri to filepath', function()
|
describe('uri to filepath', function()
|
||||||
describe('decode Unix file path', function()
|
describe('decode Unix file path', function()
|
||||||
it('file path includes only ascii charactors', function()
|
it('file path includes only ascii characters', function()
|
||||||
exec_lua("uri = 'file:///Foo/Bar/Baz.txt'")
|
exec_lua("uri = 'file:///Foo/Bar/Baz.txt'")
|
||||||
|
|
||||||
eq('/Foo/Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)"))
|
eq('/Foo/Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('local file path without hostname', function()
|
||||||
|
exec_lua("uri = 'file:/Foo/Bar/Baz.txt'")
|
||||||
|
|
||||||
|
eq('/Foo/Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)"))
|
||||||
|
end)
|
||||||
|
|
||||||
it('file path including white space', function()
|
it('file path including white space', function()
|
||||||
exec_lua("uri = 'file:///Foo%20/Bar/Baz.txt'")
|
exec_lua("uri = 'file:///Foo%20/Bar/Baz.txt'")
|
||||||
|
|
||||||
@ -85,6 +91,15 @@ describe('URI methods', function()
|
|||||||
eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case))
|
eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('local file path without hostname', function()
|
||||||
|
local test_case = [[
|
||||||
|
local uri = 'file:/C:/Foo/Bar/Baz.txt'
|
||||||
|
return vim.uri_to_fname(uri)
|
||||||
|
]]
|
||||||
|
|
||||||
|
eq('C:\\Foo\\Bar\\Baz.txt', exec_lua(test_case))
|
||||||
|
end)
|
||||||
|
|
||||||
it('file path includes only ascii charactors with encoded colon character', function()
|
it('file path includes only ascii charactors with encoded colon character', function()
|
||||||
local test_case = [[
|
local test_case = [[
|
||||||
local uri = 'file:///C%3A/Foo/Bar/Baz.txt'
|
local uri = 'file:///C%3A/Foo/Bar/Baz.txt'
|
||||||
@ -125,6 +140,12 @@ describe('URI methods', function()
|
|||||||
return vim.uri_to_fname('JDT://content/%5C/')
|
return vim.uri_to_fname('JDT://content/%5C/')
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('uri_to_fname returns non-file scheme URI without authority unchanged', function()
|
||||||
|
eq('zipfile:/path/to/archive.zip%3A%3Afilename.txt', exec_lua [[
|
||||||
|
return vim.uri_to_fname('zipfile:/path/to/archive.zip%3A%3Afilename.txt')
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('decode URI without scheme', function()
|
describe('decode URI without scheme', function()
|
||||||
@ -146,5 +167,14 @@ describe('URI methods', function()
|
|||||||
]], uri)
|
]], uri)
|
||||||
eq(uri, exec_lua(test_case))
|
eq(uri, exec_lua(test_case))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris without authority', function()
|
||||||
|
local uri = 'zipfile:/path/to/archive.zip%3A%3Afilename.txt'
|
||||||
|
local test_case = string.format([[
|
||||||
|
local uri = '%s'
|
||||||
|
return vim.uri_from_bufnr(vim.uri_to_bufnr(uri))
|
||||||
|
]], uri)
|
||||||
|
eq(uri, exec_lua(test_case))
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -11,7 +11,7 @@ describe('vim.lsp.codelens', function()
|
|||||||
after_each(helpers.clear)
|
after_each(helpers.clear)
|
||||||
|
|
||||||
it('on_codelens_stores_and_displays_lenses', function()
|
it('on_codelens_stores_and_displays_lenses', function()
|
||||||
local fake_uri = "file://fake/uri"
|
local fake_uri = "file:///fake/uri"
|
||||||
local bufnr = exec_lua([[
|
local bufnr = exec_lua([[
|
||||||
fake_uri = ...
|
fake_uri = ...
|
||||||
local bufnr = vim.uri_to_bufnr(fake_uri)
|
local bufnr = vim.uri_to_bufnr(fake_uri)
|
||||||
|
@ -49,7 +49,7 @@ describe('vim.lsp.diagnostic', function()
|
|||||||
end
|
end
|
||||||
]]
|
]]
|
||||||
|
|
||||||
fake_uri = "file://fake/uri"
|
fake_uri = "file:///fake/uri"
|
||||||
|
|
||||||
exec_lua([[
|
exec_lua([[
|
||||||
fake_uri = ...
|
fake_uri = ...
|
||||||
|
@ -1147,14 +1147,14 @@ describe('LSP', function()
|
|||||||
make_edit(0, 0, 0, 3, "First ↥ 🤦 🦄")
|
make_edit(0, 0, 0, 3, "First ↥ 🤦 🦄")
|
||||||
},
|
},
|
||||||
textDocument = {
|
textDocument = {
|
||||||
uri = "file://fake/uri";
|
uri = "file:///fake/uri";
|
||||||
version = editVersion
|
version = editVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
before_each(function()
|
before_each(function()
|
||||||
target_bufnr = exec_lua [[
|
target_bufnr = exec_lua [[
|
||||||
local bufnr = vim.uri_to_bufnr("file://fake/uri")
|
local bufnr = vim.uri_to_bufnr("file:///fake/uri")
|
||||||
local lines = {"1st line of text", "2nd line of 语text"}
|
local lines = {"1st line of text", "2nd line of 语text"}
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
||||||
return bufnr
|
return bufnr
|
||||||
@ -1234,7 +1234,7 @@ describe('LSP', function()
|
|||||||
make_edit(row, 0, row, 1000, new_line)
|
make_edit(row, 0, row, 1000, new_line)
|
||||||
},
|
},
|
||||||
textDocument = {
|
textDocument = {
|
||||||
uri = "file://fake/uri";
|
uri = "file:///fake/uri";
|
||||||
version = editVersion
|
version = editVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1252,7 +1252,7 @@ describe('LSP', function()
|
|||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
local ret = exec_lua [[
|
local ret = exec_lua [[
|
||||||
local bufnr = vim.uri_to_bufnr("file://fake/uri")
|
local bufnr = vim.uri_to_bufnr("file:///fake/uri")
|
||||||
local lines = {
|
local lines = {
|
||||||
"Original Line #1",
|
"Original Line #1",
|
||||||
"Original Line #2"
|
"Original Line #2"
|
||||||
@ -1532,19 +1532,19 @@ describe('LSP', function()
|
|||||||
it('Convert Location[] to items', function()
|
it('Convert Location[] to items', function()
|
||||||
local expected = {
|
local expected = {
|
||||||
{
|
{
|
||||||
filename = 'fake/uri',
|
filename = '/fake/uri',
|
||||||
lnum = 1,
|
lnum = 1,
|
||||||
col = 3,
|
col = 3,
|
||||||
text = 'testing'
|
text = 'testing'
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
local actual = exec_lua [[
|
local actual = exec_lua [[
|
||||||
local bufnr = vim.uri_to_bufnr("file://fake/uri")
|
local bufnr = vim.uri_to_bufnr("file:///fake/uri")
|
||||||
local lines = {"testing", "123"}
|
local lines = {"testing", "123"}
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
||||||
local locations = {
|
local locations = {
|
||||||
{
|
{
|
||||||
uri = 'file://fake/uri',
|
uri = 'file:///fake/uri',
|
||||||
range = {
|
range = {
|
||||||
start = { line = 0, character = 2 },
|
start = { line = 0, character = 2 },
|
||||||
['end'] = { line = 0, character = 3 },
|
['end'] = { line = 0, character = 3 },
|
||||||
@ -1558,14 +1558,14 @@ describe('LSP', function()
|
|||||||
it('Convert LocationLink[] to items', function()
|
it('Convert LocationLink[] to items', function()
|
||||||
local expected = {
|
local expected = {
|
||||||
{
|
{
|
||||||
filename = 'fake/uri',
|
filename = '/fake/uri',
|
||||||
lnum = 1,
|
lnum = 1,
|
||||||
col = 3,
|
col = 3,
|
||||||
text = 'testing'
|
text = 'testing'
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
local actual = exec_lua [[
|
local actual = exec_lua [[
|
||||||
local bufnr = vim.uri_to_bufnr("file://fake/uri")
|
local bufnr = vim.uri_to_bufnr("file:///fake/uri")
|
||||||
local lines = {"testing", "123"}
|
local lines = {"testing", "123"}
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
||||||
local locations = {
|
local locations = {
|
||||||
@ -1779,14 +1779,14 @@ describe('LSP', function()
|
|||||||
local expected = {
|
local expected = {
|
||||||
{
|
{
|
||||||
col = 1,
|
col = 1,
|
||||||
filename = 'test_a',
|
filename = '/test_a',
|
||||||
kind = 'File',
|
kind = 'File',
|
||||||
lnum = 2,
|
lnum = 2,
|
||||||
text = '[File] TestA'
|
text = '[File] TestA'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
col = 1,
|
col = 1,
|
||||||
filename = 'test_b',
|
filename = '/test_b',
|
||||||
kind = 'Module',
|
kind = 'Module',
|
||||||
lnum = 4,
|
lnum = 4,
|
||||||
text = '[Module] TestB'
|
text = '[Module] TestB'
|
||||||
@ -1809,7 +1809,7 @@ describe('LSP', function()
|
|||||||
line = 2
|
line = 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uri = "file://test_a"
|
uri = "file:///test_a"
|
||||||
},
|
},
|
||||||
contanerName = "TestAContainer"
|
contanerName = "TestAContainer"
|
||||||
},
|
},
|
||||||
@ -1828,7 +1828,7 @@ describe('LSP', function()
|
|||||||
line = 4
|
line = 4
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uri = "file://test_b"
|
uri = "file:///test_b"
|
||||||
},
|
},
|
||||||
contanerName = "TestBContainer"
|
contanerName = "TestBContainer"
|
||||||
}
|
}
|
||||||
@ -1867,7 +1867,7 @@ describe('LSP', function()
|
|||||||
|
|
||||||
before_each(function()
|
before_each(function()
|
||||||
target_bufnr = exec_lua [[
|
target_bufnr = exec_lua [[
|
||||||
local bufnr = vim.uri_to_bufnr("file://fake/uri")
|
local bufnr = vim.uri_to_bufnr("file:///fake/uri")
|
||||||
local lines = {"1st line of text", "å å ɧ 汉语 ↥ 🤦 🦄"}
|
local lines = {"1st line of text", "å å ɧ 汉语 ↥ 🤦 🦄"}
|
||||||
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
|
||||||
return bufnr
|
return bufnr
|
||||||
@ -1876,7 +1876,7 @@ describe('LSP', function()
|
|||||||
|
|
||||||
local location = function(start_line, start_char, end_line, end_char)
|
local location = function(start_line, start_char, end_line, end_char)
|
||||||
return {
|
return {
|
||||||
uri = "file://fake/uri",
|
uri = "file:///fake/uri",
|
||||||
range = {
|
range = {
|
||||||
start = { line = start_line, character = start_char },
|
start = { line = start_line, character = start_char },
|
||||||
["end"] = { line = end_line, character = end_char },
|
["end"] = { line = end_line, character = end_char },
|
||||||
@ -1901,7 +1901,7 @@ describe('LSP', function()
|
|||||||
|
|
||||||
it('jumps to a LocationLink', function()
|
it('jumps to a LocationLink', function()
|
||||||
local pos = jump({
|
local pos = jump({
|
||||||
targetUri = "file://fake/uri",
|
targetUri = "file:///fake/uri",
|
||||||
targetSelectionRange = {
|
targetSelectionRange = {
|
||||||
start = { line = 0, character = 4 },
|
start = { line = 0, character = 4 },
|
||||||
["end"] = { line = 0, character = 4 },
|
["end"] = { line = 0, character = 4 },
|
||||||
|
Loading…
Reference in New Issue
Block a user