diff --git a/lua/rzls/documentstore.lua b/lua/rzls/documentstore.lua index a87f129..0b4a7e0 100644 --- a/lua/rzls/documentstore.lua +++ b/lua/rzls/documentstore.lua @@ -16,26 +16,13 @@ local M = {} ---@type rzls.VirtualDocument> local virtual_documents = {} ----@param name string ----@return number | nil -local function buffer_with_name(name) - for _, buf in ipairs(vim.api.nvim_list_bufs()) do - local buf_name = vim.api.nvim_buf_get_name(buf) - if buf_name == name then - return buf - end - end -end - -local function get_or_create_vbuffer_for_filepath(filepath, filetype) - local buf = buffer_with_name(filepath) - if not buf then - buf = vim.api.nvim_create_buf(false, false) - vim.api.nvim_buf_set_name(buf, filepath) - vim.api.nvim_set_option_value("ft", filetype, { buf = buf }) - vim.api.nvim_set_option_value("buftype", "nowrite", { buf = buf }) - end - +---comment +---@param uri string +---@param suffix razor.VirtualSuffix? +---@return number +local function get_or_create_vbuffer_for_uri(uri, suffix) + local name = uri .. razor.virtual_suffixes[suffix] + local buf = vim.uri_to_bufnr(name) return buf end @@ -44,22 +31,30 @@ end function M.register_vbufs_by_path(current_file) -- open virtual files -- - virtual_documents[current_file] = virtual_documents[current_file] or {} + current_file = vim.uri_from_fname(current_file) - if vim.tbl_isempty(virtual_documents[current_file]) then - local buf = vim.uri_to_bufnr("file://" .. current_file) + if not virtual_documents[current_file] then + local buf = vim.uri_to_bufnr(current_file) virtual_documents[current_file] = VirtualDocument:new(buf, razor.language_kinds.razor) end if virtual_documents[current_file][razor.language_kinds.csharp] == nil then - local buf = get_or_create_vbuffer_for_filepath(current_file .. razor.virtual_suffixes.csharp, "cs") + local buf = get_or_create_vbuffer_for_uri(current_file, "csharp") + vim.defer_fn(function() + -- Defer setting buftype to nowrite to let LSP attach + vim.api.nvim_set_option_value("buftype", "nowrite", { buf = buf }) + end, 250) virtual_documents[current_file][razor.language_kinds.csharp] = VirtualDocument:new(buf, razor.language_kinds.csharp) end if virtual_documents[current_file][razor.language_kinds.html] == nil then - local buf = get_or_create_vbuffer_for_filepath(current_file .. razor.virtual_suffixes.html, "html") + local buf = get_or_create_vbuffer_for_uri(current_file, "html") + vim.defer_fn(function() + -- Defer setting buftype to nowrite to let LSP attach + vim.api.nvim_set_option_value("buftype", "nowrite", { buf = buf }) + end, 250) virtual_documents[current_file][razor.language_kinds.html] = VirtualDocument:new(buf, razor.language_kinds.html) end @@ -69,7 +64,8 @@ end ---@param language_kind razor.LanguageKind function M.update_vbuf(result, language_kind) M.register_vbufs_by_path(result.hostDocumentFilePath) - local virtual_document = virtual_documents[result.hostDocumentFilePath][language_kind] + local uri = vim.uri_from_fname(result.hostDocumentFilePath) + local virtual_document = virtual_documents[uri][language_kind] virtual_document:update_content(result) @@ -81,24 +77,18 @@ end ---Creates virtual buffers for the given source buffer ---@param source_buf integer function M.register_vbufs(source_buf) - local currentFile = vim.api.nvim_buf_get_name(source_buf) + -- local currentFile = vim.api.nvim_buf_get_name(source_buf) + local currentFile = vim.uri_from_bufnr(source_buf) + currentFile = vim.uri_to_fname(currentFile) return M.register_vbufs_by_path(currentFile) end ----Converts a RPC return URI to a file path ----@param uri string ----@return string -local function uri_to_path(uri) - local path = uri:gsub("file://", "") - return path -end - ---@param uri string ---@param type razor.LanguageKind ---@param version integer | "any"? ---@return rzls.VirtualDocument | nil function M.get_virtual_document(uri, type, version) - local doc = virtual_documents[uri_to_path(uri)] + local doc = virtual_documents[uri] if type == razor.language_kinds.razor then return doc end diff --git a/lua/rzls/health.lua b/lua/rzls/health.lua index 0f34560..0a1f411 100644 --- a/lua/rzls/health.lua +++ b/lua/rzls/health.lua @@ -18,9 +18,16 @@ M.check = function() for _, lang in pairs({ "csharp", "html" }) do local doc = docs[razor.language_kinds[lang]] - if doc and doc.buf then + if doc and doc.buf and doc.path then vim.health.ok( - " " .. lang .. " virtual document found: " .. doc.buf .. " v: " .. doc.host_document_version + " " + .. lang + .. " virtual document found: [buf:" + .. doc.buf + .. "] [v:" + .. doc.host_document_version + .. "]" + .. doc.path ) else vim.health.error(" " .. lang .. " virtual document not found") diff --git a/lua/rzls/server/methods/definition.lua b/lua/rzls/server/methods/definition.lua index 03902b8..c8eb86c 100644 --- a/lua/rzls/server/methods/definition.lua +++ b/lua/rzls/server/methods/definition.lua @@ -6,24 +6,21 @@ local razor = require("rzls.razor") return function(params) ---@type lsp.Position local position = params.position - ---@type integer - local razor_bufnr = vim.uri_to_bufnr(params.textDocument.uri) - local razor_docname = vim.api.nvim_buf_get_name(razor_bufnr) - local rvd = documentstore.get_virtual_document(razor_docname, razor.language_kinds.razor) + local rvd = documentstore.get_virtual_document(params.textDocument.uri, razor.language_kinds.razor) assert(rvd, "Could not find virtual document") local client = rvd:get_lsp_client() assert(client, "Could not find Razor Client") local language_query_response = client.request_sync("razor/languageQuery", { position = position, - uri = vim.uri_from_bufnr(razor_bufnr), - }, nil, razor_bufnr) + uri = rvd.path, + }, nil, rvd.buf) assert(language_query_response) local virtual_document = documentstore.get_virtual_document( - vim.uri_from_bufnr(razor_bufnr), + rvd.path, language_query_response.result.kind, language_query_response.result.hostDocumentVersion ) @@ -37,7 +34,7 @@ return function(params) local definition_result = virtual_buf_client.request_sync("textDocument/definition", { textDocument = { - uri = vim.uri_from_bufnr(virtual_document.buf), + uri = virtual_document.path, }, position = language_query_response.result.position, }, nil, virtual_document.buf) @@ -60,10 +57,10 @@ return function(params) table.insert(response, data) elseif v.uri:match(razor.virtual_suffixes.csharp .. "$") then local mapped_loc = client.request_sync("razor/mapToDocumentRanges", { - razorDocumentUri = vim.uri_from_bufnr(razor_bufnr), + razorDocumentUri = rvd.path, kind = language_query_response.result.kind, projectedRanges = { v.range }, - }, nil, razor_bufnr) + }, nil, rvd.buf) if mapped_loc and mapped_loc.result and mapped_loc.result.ranges[1] then ---@type lsp.Definition local data = { diff --git a/lua/rzls/server/methods/hover.lua b/lua/rzls/server/methods/hover.lua index 906e206..08641ef 100644 --- a/lua/rzls/server/methods/hover.lua +++ b/lua/rzls/server/methods/hover.lua @@ -6,24 +6,21 @@ local razor = require("rzls.razor") return function(params) ---@type lsp.Position local position = params.position - ---@type integer - local razor_bufnr = vim.uri_to_bufnr(params.textDocument.uri) - local razor_docname = vim.api.nvim_buf_get_name(razor_bufnr) - local rvd = documentstore.get_virtual_document(razor_docname, razor.language_kinds.razor) + local rvd = documentstore.get_virtual_document(params.textDocument.uri, razor.language_kinds.razor) assert(rvd, "Could not find virtual document") local client = rvd:get_lsp_client() assert(client, "Could not find Razor Client") local language_query_response = client.request_sync("razor/languageQuery", { position = position, - uri = vim.uri_from_bufnr(razor_bufnr), - }, nil, razor_bufnr) + uri = rvd.path, + }, nil, rvd.buf) assert(language_query_response) local virtual_document = documentstore.get_virtual_document( - vim.uri_from_bufnr(razor_bufnr), + rvd.path, language_query_response.result.kind, language_query_response.result.hostDocumentVersion ) @@ -37,7 +34,7 @@ return function(params) local hover_result = virtual_buf_client.request_sync("textDocument/hover", { textDocument = { - uri = vim.uri_from_bufnr(virtual_document.buf), + uri = virtual_document.path, }, position = language_query_response.result.position, }, nil, virtual_document.buf) @@ -47,10 +44,10 @@ return function(params) end local response = client.request_sync("razor/mapToDocumentRanges", { - razorDocumentUri = vim.uri_from_bufnr(razor_bufnr), + razorDocumentUri = rvd.path, kind = language_query_response.result.kind, projectedRanges = { hover_result.result.range }, - }, nil, razor_bufnr) + }, nil, rvd.buf) if response and response.result ~= nil and response.result.ranges[1] ~= nil then ---@type lsp.Hover diff --git a/lua/rzls/server/methods/references.lua b/lua/rzls/server/methods/references.lua index c648592..58b3b4b 100644 --- a/lua/rzls/server/methods/references.lua +++ b/lua/rzls/server/methods/references.lua @@ -7,23 +7,21 @@ return function(params) ---@type lsp.Position local position = params.position ---@type integer - local razor_bufnr = vim.uri_to_bufnr(params.textDocument.uri) - local razor_docname = vim.api.nvim_buf_get_name(razor_bufnr) - local rvd = documentstore.get_virtual_document(razor_docname, razor.language_kinds.razor) + local rvd = documentstore.get_virtual_document(params.textDocument.uri, razor.language_kinds.razor) assert(rvd, "Could not find virtual document") local client = rvd:get_lsp_client() assert(client, "Could not find Razor Client") local language_query_response = client.request_sync("razor/languageQuery", { position = position, - uri = vim.uri_from_bufnr(razor_bufnr), - }, nil, razor_bufnr) + uri = rvd.path, + }, nil, rvd.buf) assert(language_query_response) local virtual_document = documentstore.get_virtual_document( - vim.uri_from_bufnr(razor_bufnr), + rvd.path, language_query_response.result.kind, language_query_response.result.hostDocumentVersion ) @@ -37,7 +35,7 @@ return function(params) local references_result = virtual_buf_client.request_sync("textDocument/references", { textDocument = { - uri = vim.uri_from_bufnr(virtual_document.buf), + uri = virtual_document.path, }, position = language_query_response.result.position, context = { @@ -63,10 +61,10 @@ return function(params) table.insert(response, data) elseif v.uri:match(razor.virtual_suffixes.csharp .. "$") then local mapped_loc = client.request_sync("razor/mapToDocumentRanges", { - razorDocumentUri = vim.uri_from_bufnr(razor_bufnr), + razorDocumentUri = rvd.path, kind = language_query_response.result.kind, projectedRanges = { v.range }, - }, nil, razor_bufnr) + }, nil, rvd.buf) if mapped_loc and mapped_loc.result and mapped_loc.result.ranges[1] then ---@type lsp.Definition local data = { diff --git a/lua/rzls/server/methods/rename.lua b/lua/rzls/server/methods/rename.lua index 15e0535..7a8dd35 100644 --- a/lua/rzls/server/methods/rename.lua +++ b/lua/rzls/server/methods/rename.lua @@ -16,18 +16,16 @@ return function(params) ---@type lsp.Position local position = params.position ---@type integer - local razor_bufnr = vim.uri_to_bufnr(params.textDocument.uri) - local razor_docname = vim.api.nvim_buf_get_name(razor_bufnr) - local rvd = documentstore.get_virtual_document(razor_docname, razor.language_kinds.razor) + local rvd = documentstore.get_virtual_document(params.textDocument.uri, razor.language_kinds.razor) assert(rvd, "Could not find virtual document") local client = rvd:get_lsp_client() assert(client, "Could not find Razor Client") local language_query_response = client.request_sync("razor/languageQuery", { position = position, - uri = vim.uri_from_bufnr(razor_bufnr), - }, nil, razor_bufnr) + uri = rvd.path, + }, nil, rvd.buf) assert(language_query_response) @@ -38,7 +36,7 @@ return function(params) end local csvd = documentstore.get_virtual_document( - razor_docname, + params.textDocument.uri, razor.language_kinds.csharp, language_query_response.result.hostDocumentVersion ) @@ -49,11 +47,11 @@ return function(params) local edits = roslyn_client.request_sync("textDocument/rename", { textDocument = { - uri = vim.uri_from_bufnr(csvd.buf), + uri = csvd.path, }, position = language_query_response.result.position, newName = params.newName, - }, nil, razor_bufnr) + }, nil, rvd.buf) assert(edits and not edits.err and edits.result, "Rename request failed") ---@type lsp.WorkspaceEdit @@ -70,10 +68,10 @@ return function(params) local remapped_edits = {} for _, edit in ipairs(changes.edits) do local remapped_response = razor_client.request_sync("razor/mapToDocumentRanges", { - razorDocumentUri = vim.uri_from_bufnr(razor_bufnr), + razorDocumentUri = rvd.path, kind = razor.language_kinds.csharp, projectedRanges = { edit.range }, - }, nil, razor_bufnr) + }, nil, rvd.buf) if remapped_response and remapped_response.result ~= nil and remapped_response.result.ranges ~= nil then for _, range in ipairs(remapped_response.result.ranges) do diff --git a/lua/rzls/server/methods/signaturehelp.lua b/lua/rzls/server/methods/signaturehelp.lua index 0a87728..5515b63 100644 --- a/lua/rzls/server/methods/signaturehelp.lua +++ b/lua/rzls/server/methods/signaturehelp.lua @@ -6,19 +6,16 @@ local razor = require("rzls.razor") return function(params) ---@type lsp.Position local position = params.position - ---@type integer - local razor_bufnr = vim.uri_to_bufnr(params.textDocument.uri) - local razor_docname = vim.api.nvim_buf_get_name(razor_bufnr) - local rvd = documentstore.get_virtual_document(razor_docname, razor.language_kinds.razor) + local rvd = documentstore.get_virtual_document(params.textDocument.uri, razor.language_kinds.razor) assert(rvd, "Could not find virtual document") local client = rvd:get_lsp_client() assert(client, "Could not find Razor Client") local language_query_response = client.request_sync("razor/languageQuery", { position = position, - uri = vim.uri_from_bufnr(razor_bufnr), - }, nil, razor_bufnr) + uri = rvd.path, + }, nil, rvd.buf) assert(language_query_response) @@ -26,7 +23,7 @@ return function(params) assert(lsp_client, "Could not find LSP Client for response type: " .. language_query_response.result.kind) local vd = documentstore.get_virtual_document( - razor_docname, + rvd.path, language_query_response.result.kind, language_query_response.result.hostDocumentVersion ) @@ -35,13 +32,13 @@ return function(params) ---@type lsp.SignatureHelpParams local sigHelpReq = { textDocument = { - uri = vim.uri_from_bufnr(vd.buf), + uri = vd.path, }, position = language_query_response.result.position, context = params.context, } - local sig_help = lsp_client.request_sync("textDocument/signatureHelp", sigHelpReq, nil, razor_bufnr) + local sig_help = lsp_client.request_sync("textDocument/signatureHelp", sigHelpReq, nil, rvd.buf) if not sig_help or sig_help.err then return nil diff --git a/tests/rzls/documentstore_spec.lua b/tests/rzls/documentstore_spec.lua index 4f4abea..1b00548 100644 --- a/tests/rzls/documentstore_spec.lua +++ b/tests/rzls/documentstore_spec.lua @@ -7,7 +7,7 @@ describe("documentstore", function() it("create and retreive docs", function() local path = "tests/rzls/fixtures/test2.razor" local path_prefix = vim.loop.cwd() .. "/" - local full_path = path_prefix .. path + local full_path = "file://" .. path_prefix .. path vim.cmd.edit({ args = { path } }) local init_buf = vim.api.nvim_list_bufs() documentstore.register_vbufs(init_buf[1])