From 68484a2f17583428308427fd16c494e5ba204bc5 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Thu, 16 Nov 2023 16:10:26 +0100 Subject: use a global mapping of open files This allows us to support opening a single file in multiple language server instances. This can be useful when combining for example a latex and a language tool language server. --- init.lua | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'init.lua') diff --git a/init.lua b/init.lua index 16e3950..43d87cd 100644 --- a/init.lua +++ b/init.lua @@ -625,8 +625,8 @@ end local function ls_send_did_change(ls, file) lspc.log('send didChange') - local new_version = assert(ls.open_files[file.path]).version + 1 - ls.open_files[file.path].version = new_version + local new_version = assert(lspc.open_files[file.path]).version + 1 + lspc.open_files[file.path].version = new_version local document = {uri = path_to_uri(file.path), version = new_version} local changes = {{text = file:content(0, file.size)}} @@ -978,7 +978,7 @@ end -- save the diagnostics received for a file uri local function lspc_handle_publish_diagnostics(ls, uri, diagnostics) local file_path = uri_to_path(uri) - local file = ls.open_files[file_path] + local file = lspc.open_files[file_path] if file then for _, diagnostic in ipairs(diagnostics) do -- We convert the lsp_range to a vis_range here to do it only once. @@ -1097,23 +1097,36 @@ local function lspc_get_usable_ls(syntax) end local function lspc_close(ls, file) - if not ls.open_files[file.path] then + if not lspc.open_files[file.path] then return file.path .. ' not open' end ls_send_notification(ls, 'textDocument/didClose', { textDocument = {uri = path_to_uri(file.path)}, }) - ls.open_files[file.path] = nil + lspc.open_files[file.path] = nil + file.lspc = nil end -- register a file as open with a language server and setup a close and save event handlers -- A file must be opened before any textDocument functions can be used with it. local function lspc_open(ls, win, file) -- already opened - if ls.open_files[file.path] then + if lspc.open_files[file.path] then return file.path .. ' already open' end + local lspc_file_handle = lspc.open_files[file.path] + if not lspc_file_handle then + lspc_file_handle = { + file = file, + version = 0, + diagnostics = {}, + language_servers = {}, + } + end + table.insert(lspc_file_handle.language_servers, ls) + lspc.open_files[file.path] = lspc_file_handle + local params = { textDocument = { uri = 'file://' .. file.path, @@ -1123,12 +1136,11 @@ local function lspc_open(ls, win, file) }, } - ls.open_files[file.path] = {file = file, version = 0, diagnostics = {}} ls_send_notification(ls, 'textDocument/didOpen', params) vis.events.subscribe(vis.events.FILE_CLOSE, function(file) -- luacheck: ignore file for _, ls in pairs(lspc.running) do -- luacheck: ignore ls - if ls.open_files[file.path] then + if lspc.open_files[file.path] then lspc_close(ls, file) end end @@ -1139,7 +1151,7 @@ local function lspc_open(ls, win, file) ls.capabilities.textDocumentSync.save then vis.events.subscribe(vis.events.FILE_SAVE_POST, function(file, path) -- luacheck: ignore file for _, ls in pairs(lspc.running) do -- luacheck: ignore ls - if ls.open_files[file.path] then + if lspc.open_files[file.path] then local params = {textDocument = {uri = path_to_uri(path)}} -- luacheck: ignore params ls_send_notification(ls, 'textDocument/didSave', params) end @@ -1242,7 +1254,7 @@ local function lspc_method_doc_pos(ls, method, win, argv, additional_params) return 'language server ' .. ls.name .. ' does not provide ' .. method end - if not ls.open_files[win.file.path] then + if not lspc.open_files[win.file.path] then lspc_open(ls, win, win.file) end @@ -1276,11 +1288,11 @@ local lspc_goto_location_methods = { } local function lspc_goto_next_diagnostic(ls, win, reverse) - if not ls.open_files[win.file.path] then + if not lspc.open_files[win.file.path] then lspc_open(ls, win, win.file) end - local open_file = ls.open_files[win.file.path] + local open_file = lspc.open_files[win.file.path] local diagnostics = open_file.diagnostics if not diagnostics or not #diagnostics then @@ -1325,11 +1337,11 @@ local function lspc_goto_next_diagnostic(ls, win, reverse) end local function lspc_show_diagnostic(ls, win, line) - if not ls.open_files[win.file.path] then + if not lspc.open_files[win.file.path] then lspc_open(ls, win, win.file) end - local open_file = ls.open_files[win.file.path] + local open_file = lspc.open_files[win.file.path] local diagnostics = open_file.diagnostics if not diagnostics or #diagnostics == 0 then @@ -1439,7 +1451,7 @@ vis:command_register('lspc-rename', function(argv, _, win) return end - if not ls.open_files[win.file.path] then + if not lspc.open_files[win.file.path] then lspc_open(ls, win, win.file) end @@ -1462,7 +1474,7 @@ vis:command_register('lspc-format', function(_, _, win) return end - if not ls.open_files[win.file.path] then + if not lspc.open_files[win.file.path] then lspc_open(ls, win, win.file) end @@ -1591,7 +1603,7 @@ vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win) return end - local open_file = ls.open_files[win.file.path] + local open_file = lspc.open_files[win.file.path] if open_file and open_file.diagnostics and lspc.highlight_diagnostics then lspc_highlight_diagnostics(win, open_file.diagnostics) end -- cgit v1.2.3