-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Correctly detect the project runtime based on the active language server
- Loading branch information
1 parent
be4de74
commit d04059e
Showing
5 changed files
with
171 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
local log = require("neotest-java.logger") | ||
local lsp = require("neotest-java.lsp") | ||
local nio = require("nio") | ||
|
||
local COMPILER = "org.eclipse.jdt.core.compiler.source" | ||
local LOCATION = "org.eclipse.jdt.ls.core.vm.location" | ||
|
||
local function extract_runtime(bufnr) | ||
local uri = vim.uri_from_bufnr(bufnr) | ||
local error, settings, client = lsp.execute_command({ | ||
command = "java.project.getSettings", | ||
arguments = { uri, { COMPILER, LOCATION } }, | ||
}, bufnr) | ||
|
||
if error ~= nil then | ||
return | ||
end | ||
|
||
local config = client.config.settings.java or {} | ||
config = config.configuration or {} | ||
|
||
local runtimes = config.runtimes | ||
local location = vim.env.JAVA_HOME | ||
local compiler = settings[COMPILER] | ||
|
||
-- we can early exit with location here | ||
if settings[LOCATION] then | ||
location = settings[LOCATION] | ||
else | ||
-- go over available runtimes and resolve it | ||
for _, runtime in ipairs(runtimes or {}) do | ||
-- default runtimes get priority | ||
if runtime.default == true then | ||
location = runtime.path | ||
break | ||
end | ||
-- match runtime against compliance version | ||
local match = runtime.name:match(".*-(.*)") | ||
if match and match == compiler then | ||
location = runtime.path | ||
break | ||
end | ||
end | ||
end | ||
|
||
if location and nio.fn.isdirectory(location) == 0 then | ||
log.error(string.format("Invalid java runtime path location %s", location)) | ||
return | ||
end | ||
return location | ||
end | ||
|
||
---@return string | nil | ||
local function get_runtime(opts) | ||
-- todo: this is not robust, there is no way to know where this is triggered from and if the current buffer is actually a 'java' one needs to be changed !!! | ||
local bufnr = nio.api.nvim_get_current_buf() | ||
local runtime = extract_runtime(bufnr) | ||
if runtime and #runtime > 0 then | ||
return runtime | ||
end | ||
log.error("Unable to extract project runtime") | ||
return nil | ||
end | ||
|
||
return get_runtime |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
local log = require("neotest-java.logger") | ||
local nio = require("nio") | ||
|
||
-- table that holds the language server settings, this is mostly done for interfacing with coc.nvim, since native neovim lsp clients hold their settings in the clients table | ||
local SETTINGS = {} | ||
|
||
local function execute_command(command, bufnr) | ||
if vim.g.did_coc_loaded ~= nil then | ||
-- cache the settings in case we use coc, since there is no way to obtain the client's settings | ||
-- directly from the coc.nvim api, unlike with native lsp | ||
SETTINGS = nio.fn["coc#util#get_config"]("java") | ||
else | ||
-- native lsp settings are contained in the client table, we are going to use those when executing | ||
-- the native client request sync call. | ||
SETTINGS = {} | ||
end | ||
|
||
if vim.g.did_coc_loaded ~= nil then | ||
if not command.arguments then | ||
command.arguments = {} | ||
end | ||
if type(command.arguments) ~= "table" then | ||
command.arguments = { command.arguments } | ||
end | ||
local ok, result = pcall(nio.fn.CocAction, "runCommand", command.command, unpack(command.arguments)) | ||
if not ok or not result then | ||
log.warn( | ||
string.format( | ||
"Unable to run lsp %s command with payload %s", | ||
command.command, | ||
vim.inspect(command.arguments) | ||
) | ||
) | ||
end | ||
local error = not ok and result ~= vim.NIL and { message = result } or nil | ||
return error, | ||
result, | ||
{ | ||
-- adapter for the native lsp client talbe format, to simplify external clients using this interface to talk to the lsp client, which ever it happens to be | ||
name = "jdtls", | ||
config = { | ||
settings = { | ||
java = SETTINGS, | ||
}, | ||
}, | ||
} | ||
else | ||
local clients = {} | ||
for _, c in pairs(vim.lsp.get_clients({ bufnr = bufnr }) or {}) do | ||
local command_provider = c.server_capabilities.executeCommandProvider | ||
local commands = type(command_provider) == "table" and command_provider.commands or {} | ||
if vim.tbl_contains(commands, command.command) then | ||
table.insert(clients, c) | ||
end | ||
end | ||
if vim.tbl_count(clients) == 0 then | ||
log.warn(string.format("Unable to find lsp client that supports %s", command.command)) | ||
else | ||
local response, error = clients[1].request_sync("workspace/executeCommand", command) | ||
if error then | ||
log.warn( | ||
string.format( | ||
"Unable to run lsp %s command with payload %s", | ||
command.command, | ||
vim.sinepct(command.arguments) | ||
) | ||
) | ||
end | ||
return error, response.result, clients[1] | ||
end | ||
end | ||
end | ||
|
||
return { | ||
execute_command = execute_command, | ||
} |