Files
nvim/lua/conf/plugins/jdtls.lua
2025-05-06 16:51:24 -05:00

151 lines
5.3 KiB
Lua

local misc = require("core.misc")
local lsp = require("core.lsp.functions")
local map, auto = misc.map, misc.auto
return { "mfussenegger/nvim-jdtls",
disable = not vim.fn.has("nvim-0.6.0"),
requires = "mfussenegger/nvim-dap",
function()
auto("FileType", {
pattern = "java",
callback = function()
local jdtls = require("jdtls")
local jdtls_install = require("mason-registry").get_package("jdtls"):get_install_path()
-- make sure to check if things with 💀 need updating
local config = {
cmd = {
"/usr/lib/jvm/openjdk21/bin/java", -- 💀
"-jar", vim.fn.glob(jdtls_install.."/plugins/org.eclipse.equinox.launcher_*.jar"), -- 💀
"-configuration", jdtls_install.."/config_linux",
"-data", vim.fn.stdpath("cache").."/nvim-jdtls",
"--add-modules=ALL-SYSTEM",
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
"--add-opens", "java.base/java.util=ALL-UNNAMED",
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.level=ALL",
"-Dlog.protocol=true",
"-Dosgi.bundles.defaultStartLevel=4",
"-Xmx1G",
},
root_dir = vim.fs.dirname(vim.fs.find({
"gradlew",
".git",
"mvnw",
"settings.gradle", -- Gradle (multi-project)
"settings.gradle.kts", -- Gradle (multi-project)
"build.xml", -- Ant
"pom.xml", -- Maven
}, { upward = true })[1]),
-- don"t print out status messages
handlers = {
["language/status"] = function() end
},
on_attach = function(_, bufnr)
-- add some jdtls specific mappings
local opts = { buffer = bufnr }
map("n", "cri", jdtls.organize_imports, opts)
map("n", "crv", jdtls.extract_variable, opts)
map("n", "crc", jdtls.extract_constant, opts)
map("x", "crv", function() jdtls.extract_variable(true) end, opts)
map("x", "crc", function() jdtls.extract_constant(true) end, opts)
map("x", "crm", function() jdtls.extract_method(true) end, opts)
pcall(vim.lsp.codelens.refresh)
auto("BufWritePost", {
buffer = bufnr,
desc = "refresh codelens",
callback = function()
pcall(vim.lsp.codelens.refresh)
end
})
end,
capabilities = lsp.capabilities
}
-- generate the path to the java file(s)
---@type string|nil
local cache_path = vim.fs.joinpath(vim.fn.stdpath("cache"), "/JavaVersion.class")
---@type string|nil
local src_path = vim.fs.joinpath(vim.fn.stdpath("config"), "/extras/JavaVersion.java")
-- if either path is invalid
if not cache_path or not src_path then
return
end
--- build a cache of the JavaVersion code
local function build_cache()
-- check if we have javac
vim.system({ "javac" }, {}, function(out)
if out.code == 127 then
cache_path = nil
return
end
-- compile our code
vim.system({ "javac", src_path, "-d", vim.fn.stdpath("cache") }, {}, function(out)
if out.code ~= 0 then
cache_path = nil
end
end)
end)
end
-- check if we have a compiled version of JavaVersion
local f, _ = io.open(cache_path, "r")
if not f then -- if we don"t have a cache
build_cache()
else
io.close(f)
end
-- check the java version
local buffer = {}
vim.fn.jobstart({
config.cmd[1],
(cache_path and "JavaVersion") or src_path
}, {
cwd = vim.fn.stdpath("cache"),
stdin = nil,
on_stdout = function(_, data, _)
table.insert(buffer, table.concat(data))
end,
on_exit = function(_, exit_code, _)
local v = vim.version.parse(table.concat(buffer))
-- if there"s an error, no version info, or the java version is
-- less than 17 stop the lsp from starting
if exit_code ~= 0 then
vim.notify(string.format(
"java version check failed: exit code %s", exit_code),
vim.log.levels.ERROR, { title = misc.appid })
vim.notify(string.format(
"%s", vim.inspect(buffer)),
vim.log.levels.ERROR, { title = misc.appid })
return
elseif not v then
vim.notify("no java version info found", vim.log.levels.ERROR,
{ title = misc.appid })
return
elseif v.major < 17 then
vim.notify(string.format(
"java version %s < 17.0.0 Cannot run jdtls, bailing out",
v[1].."."..v[2].."."..v[3]),
vim.log.levels.ERROR, { title = misc.appid })
return
end
-- start lsp
jdtls.start_or_attach(config)
end
})
end
})
end
}