From f91eb2f3a2a9b78b1bcc8961c235e665ef06dce2 Mon Sep 17 00:00:00 2001 From: Samuel Cobb <68509699+sjcobb2022@users.noreply.github.com> Date: Sat, 18 Mar 2023 14:25:38 +0000 Subject: [PATCH] feat(pack/java): add Java Language Pack (#86) * initial commit * debugging * attach jdtls * back to basics * setup debugging * parsing opts test * pass opts to start_or_attach * remove ft as test * add notif message * removed root_dir temporarily * use .project as a root marker for eclipse projects * added server * test jdtls without blocking * workspace dir notify * working... * forgot skip_setup * identified issue * try attaching ft * setup server * add autocmd * server config * manually add ft * don't provide cmd * view default settings * try lsp method * put test notify * back to old method * notify default config * only print messsage * default opts * list commands * default thing * try again * remove accidental changes * try with default config again * callbacks * It don't load plugin * rm ensure installed * attempt 2 * comment out for now * use setup handler? * don't block stopping * reformatting * reference self * add a dependency * use setup_handlers from mason-lspconfig * add to skip_setup again * verify attach with callback * change dependencies around * more comments * only necessary messages * remove ignore again * root_dir as string? * try require mason-lspconfig * skip jdtls setup * dump opts * if opts_ null * attach server * begin dependencies again * convert * print * not attaching correctly * dump opts * custom on_attach * lsp.opn_attach * removed dependencies from mason-lspconfiog * inspect server_capabilities * pass bufnr as well * add error log messages and fix os detection * fix floor in logic * add clang_format with null0ls * allow user extensibility * other way round * gen opts * return opts * inspect opts * insert unique print * wrap in table * print root_dir * inspect opts in config * opts * error with merge * list unique * test * test2 * deep extend * set opts * return opts again * functional * remove debug printing * cleanup and comments * try get java-debug-adapter install_path * try javadbg * javadbg does not work * added java-test * fix debug adapters * print bundles for debugging * reformat bundles * inline * add dap * don't pass func unto setup_dap * dap print * else * print test * notify * add util * setup dap before attach * setup_dap in autocmd * setup_dap_main_class_configs is required. use in autocmd * add to on_attach anyway * set autocmd for LspAttach * wrong function location * test options for placement * add autocmd into on_attach to access buff * insepct args buf * move attach again * remove err * add debugging * utilSSS * print proper * more debugging * try matching pattern properly * try printing name of buf * pattern list? * general pattern for ft * move to config * autocmd pos * Complete Debugging * ensure client is jdtls * add comments * update README * pass lint * use stylua --- lua/astrocommunity/pack/java/README.md | 15 +++ lua/astrocommunity/pack/java/java.lua | 180 +++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 lua/astrocommunity/pack/java/README.md create mode 100644 lua/astrocommunity/pack/java/java.lua diff --git a/lua/astrocommunity/pack/java/README.md b/lua/astrocommunity/pack/java/README.md new file mode 100644 index 000000000..e3baa3d03 --- /dev/null +++ b/lua/astrocommunity/pack/java/README.md @@ -0,0 +1,15 @@ + +# Java Language Pack + +Requires: +- `JDK-17` or higher to function. + +This plugin pack does the following: + +- Adds `java` treesitter parsers +- Adds `html` treesitter parsers (XML) +- Adds `jdtls` language server +- Adds `lemminx` language server (XML) +- Adds [nvim-jdtls](https://github.com/mfussenegger/nvim-jdtls) for language specific tooling +- Adds `clang_format` through null-ls +- Adds `javadbg` and `javatest` debug adapters for nvim-dap diff --git a/lua/astrocommunity/pack/java/java.lua b/lua/astrocommunity/pack/java/java.lua new file mode 100644 index 000000000..ba4740144 --- /dev/null +++ b/lua/astrocommunity/pack/java/java.lua @@ -0,0 +1,180 @@ +local utils = require "astrocommunity.utils" + +return { + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + -- Ensure that opts.ensure_installed exists and is a table or string "all". + if not opts.ensure_installed then + opts.ensure_installed = {} + elseif opts.ensure_installed == "all" then + return + end + -- Add the "java" and "html" language to opts.ensure_installed. + -- XML does not have it's own treesitter plugin so HTML can take over if necessary + utils.list_insert_unique(opts.ensure_installed, { "java", "html" }) + end, + }, + { + "williamboman/mason-lspconfig.nvim", + opts = function(_, opts) + -- Ensure that opts.ensure_installed exists and is a table. + if not opts.ensure_installed then opts.ensure_installed = {} end + -- Add jdtls and lemminx lsps to opts.ensure_installed using vim.list_extend. + utils.list_insert_unique(opts.ensure_installed, { "jdtls", "lemminx" }) + end, + }, + + { + "jay-babu/mason-null-ls.nvim", + opts = function(_, opts) + -- Ensure that opts.ensure_installed exists and is a table. + if not opts.ensure_installed then opts.ensure_installed = {} end + -- Add clang_format to opts.ensure_installed + utils.list_insert_unique(opts.ensure_installed, { "clang_format" }) + end, + }, + + { + "jay-babu/mason-nvim-dap.nvim", + opts = function(_, opts) + -- Ensure that opts.ensure_installed exists and is a table. + if not opts.ensure_installed then opts.ensure_installed = {} end + -- Add javadgb to required + utils.list_insert_unique(opts.ensure_installed, { "javadbg", "javatest" }) + end, + }, + + { + "mfussenegger/nvim-jdtls", + ft = { "java" }, + init = function() utils.list_insert_unique(astronvim.lsp.skip_setup, "jdtls") end, + opts = function(_, opts) + -- use this function notation to build some variables + local root_markers = { ".git", "mvnw", "gradlew", "pom.xml", "build.gradle", ".project" } + local root_dir = require("jdtls.setup").find_root(root_markers) + + -- calculate workspace dir + local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t") + local workspace_dir = vim.fn.stdpath "data" .. "/site/java/workspace-root/" .. project_name + os.execute("mkdir " .. workspace_dir) + + -- get the mason install path + local install_path = require("mason-registry").get_package("jdtls"):get_install_path() + + -- get the current OS + local os + if vim.fn.has "mac" == 1 then + os = "mac" + elseif vim.fn.has "unix" == 1 then + os = "linux" + elseif vim.fn.has "win32" == 1 then + os = "win" + end + + -- ensure that OS is valid + if not os or os == "" then + require("astronvim.utils").notify("jdtls: Could not detect valid OS", vim.log.levels.ERROR) + end + + local defaults = { + cmd = { + "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", + "-javaagent:" .. install_path .. "/lombok.jar", + "-Xms1g", + "--add-modules=ALL-SYSTEM", + "--add-opens", + "java.base/java.util=ALL-UNNAMED", + "--add-opens", + "java.base/java.lang=ALL-UNNAMED", + "-jar", + vim.fn.glob(install_path .. "/plugins/org.eclipse.equinox.launcher_*.jar"), + "-configuration", + install_path .. "/config_" .. os, + "-data", + workspace_dir, + }, + root_dir = root_dir, + settings = { + java = {}, + }, + init_options = { + bundles = { + vim.fn.glob( + require("mason-registry").get_package("java-debug-adapter"):get_install_path() + .. "/extension/server/com.microsoft.java.debug.plugin-*.jar" + ), + -- unpack remaining bundles + table.unpack( + vim.split( + vim.fn.glob( + require("mason-registry").get_package("java-test"):get_install_path() .. "/extension/server/*.jar" + ), + "\n", + {} + ) + ), + }, + }, + handlers = { + ["language/status"] = function() + -- print(result) + end, + ["$/progress"] = function() + -- disable progress updates. + end, + }, + filetypes = { "java" }, + on_attach = function(client, bufnr) + require("jdtls").setup_dap() + require("astronvim.utils.lsp").on_attach(client, bufnr) + end, + } + + -- TODO: add overwrite for on_attach + + -- ensure that table is valid + if not opts then opts = {} end + + -- extend the current table with the defaults keeping options in the user opts + -- this allows users to pass opts through an opts table in community.lua + opts = vim.tbl_deep_extend("keep", opts, defaults) + + -- send opts to config + return opts + end, + config = function(_, opts) + -- setup autocmd on filetype detect java + vim.api.nvim_create_autocmd("Filetype", { + pattern = "java", -- autocmd to start jdtls + callback = function() + if opts.root_dir and opts.root_dir ~= "" then + require("jdtls").start_or_attach(opts) + -- require('jdtls.dap').setup_dap_main_class_configs() + else + require("astronvim.utils").notify( + "jdtls: root_dir not found. Please specify a root marker", + vim.log.levels.ERROR + ) + end + end, + }) + -- create autocmd to load main class configs on LspAttach. + -- This ensures that the LSP is fully attached. + -- See https://github.com/mfussenegger/nvim-jdtls#nvim-dap-configuration + vim.api.nvim_create_autocmd("LspAttach", { + pattern = "*.java", + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + -- ensure that only the jdtls client is activated + if client.name == "jdtls" then require("jdtls.dap").setup_dap_main_class_configs() end + end, + }) + end, + }, +}