local M = {} M.setup = function() -- Java-specific settings vim.opt_local.tabstop = 4 vim.opt_local.shiftwidth = 4 vim.opt_local.expandtab = true -- Quick commands for Java vim.api.nvim_create_user_command("JavaRun", function() vim.cmd "!javac % && java %:r" end, {}) vim.api.nvim_create_user_command("JavaCompile", function() vim.cmd "!javac %" end, {}) end -- Setup jdtls when a Java file is opened M.setup_jdtls = function() local status, jdtls = pcall(require, "jdtls") if not status then print "Failed to load JDTLS plugin" return end -- Find root of project local root_markers = { ".git", "mvnw", "gradlew", "pom.xml", "build.gradle" } local root_dir = require("jdtls.setup").find_root(root_markers) if not root_dir then root_dir = vim.fn.getcwd() end -- Determine OS-specific config local os_config if vim.fn.has "mac" == 1 then os_config = "config_mac" elseif vim.fn.has "unix" == 1 then os_config = "config_linux" elseif vim.fn.has "win32" == 1 then os_config = "config_win" else os_config = "config_linux" end -- Get mason paths local mason_path = vim.fn.stdpath "data" .. "/mason" local jdtls_path = mason_path .. "/packages/jdtls" -- Check if launcher jar exists local launcher_jar = vim.fn.glob(jdtls_path .. "/plugins/org.eclipse.equinox.launcher_*.jar") if launcher_jar == "" then print "JDTLS launcher jar not found" return end -- Create workspace directory local project_name = vim.fn.fnamemodify(root_dir, ":p:h:t") local workspace_dir = vim.fn.expand "~/.cache/jdtls/workspace/" .. project_name vim.fn.mkdir(workspace_dir, "p") -- Get system Java local java_cmd = "java" local config = { cmd = { java_cmd, "-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", "-Xms1g", "--add-modules=ALL-SYSTEM", "--add-opens", "java.base/java.util=ALL-UNNAMED", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "-jar", launcher_jar, "-configuration", jdtls_path .. "/" .. os_config, "-data", workspace_dir, }, root_dir = root_dir, settings = { java = { signatureHelp = { enabled = true }, contentProvider = { preferred = "fernflower" }, completion = { favoriteStaticMembers = { "org.junit.jupiter.api.Assertions.*", "java.util.Objects.requireNonNull", "java.util.Objects.requireNonNullElse", }, }, sources = { organizeImports = { starThreshold = 9999, staticStarThreshold = 9999, }, }, codeGeneration = { toString = { template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}", }, useBlocks = true, }, configuration = { updateBuildConfiguration = "interactive", }, }, }, capabilities = require("nvchad.configs.lspconfig").capabilities, on_attach = require("nvchad.configs.lspconfig").on_attach, init_options = { bundles = {}, }, } -- Print the commands being used (for debugging) print("JDTLS launcher: " .. launcher_jar) print("JDTLS config dir: " .. jdtls_path .. "/" .. os_config) -- Start jdtls jdtls.start_or_attach(config) end return M