dots/.config/nvim/lua/jdtls/jdtls_setup.lua
2025-09-09 11:37:30 -07:00

265 lines
8.0 KiB
Lua

local utils = require("utils")
local M = {}
function M.setup()
local jdtls = require("jdtls")
local jdtls_dap = require("jdtls.dap")
local jdtls_setup = require("jdtls.setup")
local home = os.getenv("HOME")
local root_markers = { ".git", "mvnw", "gradlew" }
local root_dir = jdtls_setup.find_root(root_markers)
local project_name = vim.fn.fnamemodify(root_dir, ":p:h:t")
local workspace_dir = home .. "/.cache/jdtls/workspace/" .. project_name
local path_to_nvim_packages = home .. "/.local/share/nvim"
local path_to_mason_packages = home .. "/.local/share/nvim/mason/packages"
local path_to_jdtls = path_to_mason_packages .. "/jdtls"
local path_to_java_dap = path_to_mason_packages .. "/java-debug-adapter"
local path_to_jtest = path_to_mason_packages .. "/java-test"
local path_to_config = path_to_jdtls .. "/config_linux"
local lombok_path = path_to_jdtls .. "/lombok.jar"
local path_to_jar = vim.fn.glob(path_to_jdtls .. "/plugins/org.eclipse.equinox.launcher_*.jar", true)
local bundles = {
-- vim.fn.glob(path_to_java_dap .. "/extension/server/com.microsoft.java.debug.plugin-*.jar", true),
vim.fn.glob(
path_to_nvim_packages
.. "/java-debug/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-*.jar"
),
}
vim.list_extend(bundles, vim.split(vim.fn.glob(path_to_nvim_packages .. "/vscode-java-test/server/*.jar"), "\n"))
-- vim.list_extend(bundles, vim.split(vim.fn.glob(path_to_jtest .. "/extension/server/*.jar", true), "\n"))
local on_attach = function(_, bufnr)
-- Regular Neovim LSP client keymappings
local opts = { noremap = true, silent = true, buffer = bufnr }
local telescope = require("telescope.builtin")
utils.nmapkey("gR", telescope.lsp_references, "Go to references", opts)
utils.nmapkey("gD", jdtls.declaration, "Go to declaration", opts)
utils.nmapkey("K", jdtls.hover, "Hover text", opts)
utils.nmapkey("gd", jdtls.definition, "Go to definition", opts)
utils.nmapkey("gi", jdtls.implementation, "Go to implementation", opts)
utils.nmapkey("gt", telescope.lsp_type_definitions, "Show LSP type definitions", opts)
utils.nmapkey("<C-k>", jdtls.signature_help, "Show signature", opts)
utils.nmapkey("<leader>wa", jdtls.add_workspace_folder, "Add workspace folder", opts)
utils.nmapkey("<leader>wr", jdtls.remove_workspace_folder, "Remove workspace folder", opts)
utils.nmapkey("<leader>wl", function()
print(vim.inspect(jdtls.list_workspace_folders()))
end, "List workspace folders", opts)
utils.nmapkey("<leader>D", telescope.diagnostics({ bufnr = 0 }), "Show buffer diagnostics", opts) -- show diagnostics for file
utils.nmapkey("<leader>d", vim.diagnostic.open_float, "Show line diagnostics", opts) -- show diagnostics for line
utils.nmapkey("[d", function()
vim.diagnostic.jump({ count = -1, float = true })
end, "Go to previous diagnostic", opts) -- jump to previous diagnostic in buffer
utils.nmapkey("]d", function()
vim.diagnostic.jump({ count = 1, float = true })
end, "Go to next diagnostic", opts) -- jump to next diagnostic in buffer
utils.nmapkey("<leader>rs", "<cmd>LspRestart<cr>", "Restart LSP", opts) -- mapping to restart lsp if necessary
-- Java extensions provided by jdtls
utils.nmapkey("<leader>di", jdtls.organize_imports, "Organize imports", opts)
utils.nmapkey("<leader>dt", jdtls.test_class, "Test class", opts)
utils.nmapkey("<leader>dn", jdtls.test_nearest_method, "Test nearest method", opts)
utils.nmapkey("<leader>cf", jdtls.formatting, "LSP Format", opts)
utils.nmapkey("<C-o>", jdtls.organize_imports, "Organize imports", opts)
utils.mapkey({ "n", "v" }, "<leader>ev", jdtls.extract_variable, "Extract variable", opts)
utils.mapkey({ "n", "v" }, "<leader>ec", jdtls.extract_constant, "Extract constant", opts)
utils.mapkey({ "n", "v" }, "<leader>em", jdtls.extract_variable, "Extract method", opts)
end
local config = {
init_options = {
bundles = vim.split(vim.fn.glob("/home/iborrelli/pde/extension/server/*.jar"), "\n"),
},
flags = {
allow_incremental_sync = true,
},
on_attach = on_attach, -- We pass our on_attach keybindings to the configuration map
}
config.cmd = {
"/usr/lib/jvm/java-21-openjdk/bin/java",
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.protocol=true",
"-Dlog.level=ALL",
"-Xmx1g",
"-javaagent:" .. lombok_path,
"--add-modules=ALL-SYSTEM",
"--add-opens",
"java.base/java.util=ALL-UNNAMED",
"--add-opens",
"java.base/java.lang=ALL-UNNAMED",
"-jar",
path_to_jar,
"-configuration",
path_to_config,
"-data",
workspace_dir,
}
-- print(table.concat(config.cmd, " "))
-- print(vim.inspect(config.cmd))
config.settings = {
java = {
references = {
includeDecompiledSources = true,
},
-- format = {
-- enabled = true,
-- settings = {
-- url = vim.fn.stdpath("config") .. "/lang_servers/intellij-java-google-style.xml",
-- profile = "GoogleStyle",
-- },
-- },
eclipse = {
downloadSources = true,
},
maven = {
downloadSources = true,
},
-- signatureHelp = { enabled = true },
-- contentProvider = { preferred = "fernflower" },
implementationsCodeLens = {
enabled = true,
},
import = {
gradle = {
wrapper = {
enabled = true,
},
},
},
completion = {
favoriteStaticMembers = {
"org.hamcrest.MatcherAssert.assertThat",
"org.hamcrest.Matchers.*",
"org.hamcrest.CoreMatchers.*",
"org.junit.jupiter.api.Assertions.*",
"java.util.Objects.requireNonNull",
"java.util.Objects.requireNonNullElse",
"org.mockito.Mockito.*",
},
filteredTypes = {
"com.sun.*",
"io.micrometer.shaded.*",
"java.awt.*",
"jdk.*",
"sun.*",
},
importOrder = {
"java",
"javax",
"com",
"org",
},
},
sources = {
organizeImports = {
starThreshold = 9999,
staticStarThreshold = 9999,
},
},
-- codeGeneration = {
-- toString = {
-- template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}",
-- -- flags = {
-- -- allow_incremental_sync = true,
-- -- },
-- },
-- useBlocks = true,
-- },
configuration = {
updateBuildConfiguration = "automatic",
runtimes = {
{
name = "JavaSE-17",
path = "/usr/lib/jvm/java-17-openjdk/",
},
{
name = "JavaSE-21",
path = "/usr/lib/jvm/java-21-openjdk/",
},
},
},
-- project = {
-- referencedLibraries = {
-- "**/lib/*.jar",
-- },
-- },
},
}
-- -- LSP settings for Java.
-- local on_attach = function(_, bufnr)
-- jdtls.setup_dap({ hotcodereplace = "auto" })
-- jdtls_dap.setup_dap_main_class_configs()
-- jdtls_setup.add_commands()
--
-- -- Create a command `:Format` local to the LSP buffer
-- vim.api.nvim_buf_create_user_command(bufnr, "Format", function(_)
-- vim.lsp.buf.format()
-- end, { desc = "Format current buffer with LSP" })
--
-- require("lsp_signature").on_attach({
-- bind = true,
-- padding = "",
-- handler_opts = {
-- border = "rounded",
-- },
-- hint_prefix = "󱄑 ",
-- }, bufnr)
--
-- -- NOTE: comment out if you don't use Lspsaga
-- -- require("lspsaga").init_lsp_saga()
-- end
local capabilities = {
workspace = {
configuration = true,
},
textDocument = {
completion = {
completionItem = {
snippetSupport = true,
},
},
},
}
config.on_attach = on_attach
config.capabilities = capabilities
config.on_init = function(client, _)
client.notify("workspace/didChangeConfiguration", { settings = config.settings })
end
local extendedClientCapabilities = require("jdtls").extendedClientCapabilities
extendedClientCapabilities.resolveAdditionalTextEditsSupport = true
config.init_options = {
extendedClientCapabilities = extendedClientCapabilities,
}
-- Start Server
require("jdtls").start_or_attach(config)
-- -- Set Java Specific Keymaps
-- require("jdtls.keymaps")
end
return M