From c5227e66dd874aa15775d7c285eec173b1391ca6 Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Fri, 6 Dec 2024 23:43:46 +0100 Subject: [PATCH 1/4] fix: ignore responses from other clients There was a change a while back that makes the buf request go to all the attached clients. For Scala normally this isn't an issue at all, but if you're using co-pilot which is also a client in this situation it will fire metals requests to it which you don't want. We then throw an error in that situation while the command still worked. This is confusing for users, so this should fix the issue by filtering out the responses that don't match metals. --- lua/metals.lua | 16 ++-- lua/metals/tvp/init.lua | 178 +++++++++++++++++++++++----------------- lua/metals/util.lua | 6 ++ 3 files changed, 119 insertions(+), 81 deletions(-) diff --git a/lua/metals.lua b/lua/metals.lua index 984b44c..2b3e95c 100644 --- a/lua/metals.lua +++ b/lua/metals.lua @@ -26,11 +26,17 @@ local M = {} -- @param command_params (optional, table) Parameters to send to the server (arguments and command). -- @param callback (function) callback function for the request response. local function execute_command(command_params, callback) - lsp.buf_request(0, "workspace/executeCommand", command_params, function(err, result, ctx) - if callback then - callback(err, ctx.method, result) - elseif err then - log.error_and_show(string.format("Could not execute command: %s", err.message)) + lsp.buf_request_all(0, "workspace/executeCommand", command_params, function(responses) + local metals_id = util.find_metals_client_id() + + for client_id, response in pairs(responses) do + if client_id ~= metals_id then + return + elseif callback then + callback(response.err, response.ctx.method, responses) + elseif response.err then + log.error_and_show(string.format("Could not execute command: %s", response.err.message)) + end end end) end diff --git a/lua/metals/tvp/init.lua b/lua/metals/tvp/init.lua index 88140a6..50395b1 100644 --- a/lua/metals/tvp/init.lua +++ b/lua/metals/tvp/init.lua @@ -157,60 +157,71 @@ function Tree:tree_view_children(opts) if opts.parent_uri ~= nil then tree_view_children_params["nodeUri"] = opts.parent_uri end - vim.lsp.buf_request(valid_metals_buffer(), "metals/treeViewChildren", tree_view_children_params, function(err, result) - if err then - log.error(err) - log.error_and_show("Something went wrong while requesting tvp children. More info in logs.") - else - local new_nodes = {} - for _, node in pairs(result.nodes) do - table.insert(new_nodes, Node:new(node)) - end - if opts.parent_uri == nil then - self.children = new_nodes - else - self:update(opts.parent_uri, new_nodes) - end - -- NOTE: Not ideal to have to iterate over these again, but we want the - -- update to happen before we call this or else we'll have issues adding the - -- children to a node that doesn't yet exist. - for _, node in pairs(new_nodes) do - if node.collapse_state == collapse_state.expanded then - self:tree_view_children({ view_id = metals_packages, parent_uri = node.node_uri }) - end - end - if opts.expand then - local node = self:find(opts.parent_uri) - if node and node.collapse_state and node.collapse_state == collapse_state.collapsed then - node:expand(valid_metals_buffer()) - end - end - local additionals = opts.additionals - if additionals then - local head = table.remove(additionals, 1) - local additional_params = { - view_id = view_id, - parent_uri = head, - expand = opts.expand, - focus = opts.focus, - } - if #additionals > 1 then - additional_params.additionals = additionals - end - self:tree_view_children(additional_params) - end + vim.lsp.buf_request_all( + valid_metals_buffer(), + "metals/treeViewChildren", + tree_view_children_params, + function(responses) + local metals_id = util.find_metals_client_id() + + for client_id, response in pairs(responses) do + if client_id ~= metals_id then + return + elseif response.err then + log.error(response.err) + log.error_and_show("Something went wrong while requesting tvp children. More info in logs.") + else + local new_nodes = {} + for _, node in pairs(response.result.nodes) do + table.insert(new_nodes, Node:new(node)) + end + if opts.parent_uri == nil then + self.children = new_nodes + else + self:update(opts.parent_uri, new_nodes) + end + -- NOTE: Not ideal to have to iterate over these again, but we want the + -- update to happen before we call this or else we'll have issues adding the + -- children to a node that doesn't yet exist. + for _, node in pairs(new_nodes) do + if node.collapse_state == collapse_state.expanded then + self:tree_view_children({ view_id = metals_packages, parent_uri = node.node_uri }) + end + end + if opts.expand then + local node = self:find(opts.parent_uri) + if node and node.collapse_state and node.collapse_state == collapse_state.collapsed then + node:expand(valid_metals_buffer()) + end + end + local additionals = opts.additionals + if additionals then + local head = table.remove(additionals, 1) + local additional_params = { + view_id = view_id, + parent_uri = head, + expand = opts.expand, + focus = opts.focus, + } + if #additionals > 1 then + additional_params.additionals = additionals + end + self:tree_view_children(additional_params) + end - self:reload_and_show() - if opts.focus and not opts.additionals then - for line, node in pairs(self.lookup) do - if node.node_uri == opts.parent_uri then - api.nvim_win_set_cursor(self.win_id, { line, 0 }) - break + self:reload_and_show() + if opts.focus and not opts.additionals then + for line, node in pairs(self.lookup) do + if node.node_uri == opts.parent_uri then + api.nvim_win_set_cursor(self.win_id, { line, 0 }) + break + end + end end end end end - end) + ) end function Tree:cache() @@ -326,12 +337,19 @@ local function execute_node_command(node) if node.command ~= nil then -- Jump to the last window so this doesn't open up in the actual tvp panel vim.cmd([[wincmd p]]) - vim.lsp.buf_request(valid_metals_buffer(), "workspace/executeCommand", { + + vim.lsp.buf_request_all(valid_metals_buffer(), "workspace/executeCommand", { command = node.command.command, arguments = node.command.arguments, - }, function(err, _, _) - if err then - log.error_and_show("Unable to execute node command.") + }, function(responses) + local metals_id = util.find_metals_client_id() + + for client_id, response in pairs(responses) do + if client_id ~= metals_id then + return + elseif response.err then + log.error_and_show("Unable to execute node command.") + end end end) end @@ -451,32 +469,40 @@ local function reveal_in_tree() state.tvp_tree:open() end - vim.lsp.buf_request(valid_metals_buffer(), "metals/treeViewReveal", params, function(err, result, ctx) - if err then - log.error_and_show(string.format("Error when executing: %s. Check the metals logs for more info.", ctx.method)) - elseif result then - if result.viewId == metals_packages then - if api.nvim_get_current_win() ~= state.tvp_tree.win_id then - vim.fn.win_gotoid(state.tvp_tree.win_id) - end - - util.reverse(result.uriChain) - local head = table.remove(result.uriChain, 1) + vim.lsp.buf_request_all(valid_metals_buffer(), "metals/treeViewReveal", params, function(responses) + local metals_id = util.find_metals_client_id() - state.tvp_tree:tree_view_children({ - view_id = result.viewId, - parent_uri = head, - additionals = result.uriChain, - expand = true, - focus = true, - }) - else - log.warn_and_show( - string.format("You recieved a node for a view nvim-metals doesn't support: %s", result.viewId) + for client_id, response in pairs(responses) do + if client_id ~= metals_id then + return + elseif response.err then + log.error_and_show( + string.format("Error when executing: %s. Check the metals logs for more info.", response.ctx.method) ) + elseif response.result then + if response.result.viewId == metals_packages then + if api.nvim_get_current_win() ~= state.tvp_tree.win_id then + vim.fn.win_gotoid(state.tvp_tree.win_id) + end + + util.reverse(response.result.uriChain) + local head = table.remove(response.result.uriChain, 1) + + state.tvp_tree:tree_view_children({ + view_id = response.result.viewId, + parent_uri = head, + additionals = response.result.uriChain, + expand = true, + focus = true, + }) + else + log.warn_and_show( + string.format("You recieved a node for a view nvim-metals doesn't support: %s", response.result.viewId) + ) + end + else + log.warn_and_show(messages.scala_3_tree_view) end - else - log.warn_and_show(messages.scala_3_tree_view) end end) end) diff --git a/lua/metals/util.lua b/lua/metals/util.lua index cd8194c..67077e9 100644 --- a/lua/metals/util.lua +++ b/lua/metals/util.lua @@ -98,6 +98,12 @@ end M.is_windows = vim.loop.os_uname().version:match("Windows") +---@return integer|nil +M.find_metals_client_id = function() + local metals = vim.lsp.get_clients({ name = "metals" }) + return metals[1].id or nil +end + ---@return integer|nil M.find_metals_buffer = function() local metals_buf = nil From c22286a6a690468c57c83614f5ef1b28e8ecc471 Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Fri, 6 Dec 2024 23:46:30 +0100 Subject: [PATCH 2/4] chore: run tests on the actual current stable version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8622f4..daf6166 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: strategy: fail-fast: false matrix: - neovim_version: ['v0.10.0', 'nightly'] + neovim_version: ['v0.10.2', 'nightly'] steps: - uses: actions/checkout@v4 From 6d21dc54814f84f2b592773f9b3c4e28b985796d Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Fri, 6 Dec 2024 23:48:55 +0100 Subject: [PATCH 3/4] chore: bump version of stylua --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index daf6166..559aa1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: uses: JohnnyMorganz/stylua-action@v4.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} - version: 0.20.0 + version: 2.0.1 args: --check lua/ test: From 52258a200f3404e36e360ae13295ac2142e00e0a Mon Sep 17 00:00:00 2001 From: Chris Kipp Date: Fri, 6 Dec 2024 23:51:07 +0100 Subject: [PATCH 4/4] chore: bump version of selene --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 559aa1f..8d9c363 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,9 +26,9 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH env: - VERSION: "0.26.1" + VERSION: "0.27.1" # shashum -a 256 selene--linux.zip - SHA256_CHECKSUM: "406697af6a13027a0f95fd65a790ca0b496a28ede4d7355f4b04ebf1d640134e" + SHA256_CHECKSUM: "22dabfe070c6d10cbb0b8ae56a82abfa131fbb902bff03d9924f0f73fd3d3318" - name: Run selene run: make lint