From e9258bce3db6df60b9ed4ba716b22cd90cd952d4 Mon Sep 17 00:00:00 2001 From: Artur Shaik Date: Fri, 8 Nov 2024 16:18:13 +0600 Subject: [PATCH] minimal refactoring to use with LazyVim --- README.md | 80 +++++++++++--- autoload/jc.vim | 2 +- lua/jc.lua | 11 +- lua/jc/config.lua | 4 +- lua/jc/config/mappings.lua | 49 ++++++--- lua/jc/jdtls.lua | 46 +++++--- lua/jc/lsp.lua | 8 +- lua/jc/server.lua | 213 +++++++++++++++++++++++-------------- 8 files changed, 279 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index 01aa0e0..519be0c 100644 --- a/README.md +++ b/README.md @@ -17,26 +17,78 @@ In addition to autocompletion it can: ## Installation -Minimal setup using `vim-plug`: +Minimal setup using `LazyVim`: ``` -call plug#begin('~/.vim/plugged') - -Plug 'neovim/nvim-lspconfig' -Plug 'hrsh7th/nvim-cmp' -Plug 'hrsh7th/cmp-nvim-lsp' -Plug 'williamboman/nvim-lsp-installer' -Plug 'puremourning/vimspector' -Plug 'mfussenegger/nvim-jdtls' -Plug 'artur-shaik/jc.nvim' +return { + { + "mfussenegger/nvim-jdtls", + config = function() end, + }, + { + "puremourning/vimspector", + keys = { + { + "vr", + "VimspectorReset", + }, + { + "vb", + "VimspectorBreakpoints", + }, + }, + init = function() + vim.g.vimspector_enable_mappings = "HUMAN" + end, + }, + { + dir = "artur-shaik/jc.nvim", + name = "jc.nvim", + dependencies = { + "puremourning/vimspector", + "mfussenegger/nvim-jdtls", + "williamboman/mason.nvim", + }, + ft = { "java" }, + opts = { + java_exec = "/home/ash/.sdkman/candidates/java/17.0.7-oracle/bin/java", + keys_prefix = "'j", + settings = { + java = { + configuration = { + runtimes = { + { + name = "JavaSE-11", + path = "/home/ash/.sdkman/candidates/java/11.0.12-open/", + default = true, + }, + }, + }, + }, + }, + }, + }, +} +``` -call plug#end() +lspconfig: -lua require('jc').setup{} +```lua +return { + { + "neovim/nvim-lspconfig", + opts = { + servers = { + jdtls = {}, + }, + setup = { + jdtls = function() + return true + end, + }, + }, ``` -Execute `:PlugInstall` and restart neovim. - For triggering autocompletion automatically consider [configure nvim-cmp](https://github.com/hrsh7th/nvim-cmp/#recommended-configuration). ## Configurations diff --git a/autoload/jc.vim b/autoload/jc.vim index 2cad6f4..76c48dc 100644 --- a/autoload/jc.vim +++ b/autoload/jc.vim @@ -1,5 +1,5 @@ function! s:OnSave() - if get(g:, 'jc_autoformat_on_save', 1) + if get(g:, 'jc_autoformat_on_save', 0) if has('nvim-0.8.0') lua vim.lsp.buf.format({ async = false }) endif diff --git a/lua/jc.lua b/lua/jc.lua index db55395..6bbddf4 100644 --- a/lua/jc.lua +++ b/lua/jc.lua @@ -1,16 +1,19 @@ local lsp = require("jc.lsp") local server = require("jc.server") -local jdtls = require("jc.jdtls") M = {} local user_on_attach = function(_, _) end local config = { java_exec = "java", - jc_on_attach = function(client, bufnr) - lsp.on_attach(client, bufnr) - user_on_attach(client, bufnr) + jc_on_attach = function(args) + if args.data then + local client = vim.lsp.get_client_by_id(args.data.client_id) + lsp.on_attach(M.config, client, args.buf) + user_on_attach(client, args.buf) + end end, + keys_prefix = "j", } M.setup = function(args) diff --git a/lua/jc/config.lua b/lua/jc/config.lua index 1c6f56e..2108155 100644 --- a/lua/jc/config.lua +++ b/lua/jc/config.lua @@ -2,9 +2,9 @@ local mappings = require("jc.config.mappings") local M = {} -function M.initialize_configuration(bufnr) +function M.initialize_configuration(conf, bufnr) if vim.g.jc_default_mappings then - mappings.install_mappings(bufnr) + mappings.install_mappings(conf, bufnr) end end diff --git a/lua/jc/config/mappings.lua b/lua/jc/config/mappings.lua index ae15e4a..83042ae 100644 --- a/lua/jc/config/mappings.lua +++ b/lua/jc/config/mappings.lua @@ -1,31 +1,50 @@ local M = {} -function M.install_mappings(bufnr) +function M.install_mappings(conf, bufnr) local opts = { noremap = true, silent = true } + local prefix = conf.keys_prefix - vim.api.nvim_buf_set_keymap(bufnr, "n", "jda", "lua require('jc.vimspector').debug_attach()", opts) + vim.api.nvim_set_keymap("n", prefix .. "da", "lua require('jc.vimspector').debug_attach()", opts) - vim.api.nvim_buf_set_keymap(bufnr, "n", "ji", "lua require('jc.jdtls').organize_imports(true)", opts) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jI", + prefix .. "i", + "lua require('jc.jdtls').organize_imports(true)", + opts + ) + vim.api.nvim_buf_set_keymap( + bufnr, + "n", + prefix .. "I", "lua require('jc.jdtls').organize_imports(false)", opts ) vim.api.nvim_buf_set_keymap(bufnr, "i", "i", "lua require('jc.jdtls').organize_imports()", opts) - vim.api.nvim_buf_set_keymap(bufnr, "n", "jts", "lua require('jc.jdtls').generate_toString()", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", prefix .. "ts", "lua require('jc.jdtls').generate_toString()", opts) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jeq", + prefix .. "eq", "lua require('jc.jdtls').generate_hashCodeAndEquals()", opts ) - vim.api.nvim_buf_set_keymap(bufnr, "n", "jA", "lua require('jc.jdtls').generate_accessors()", opts) - vim.api.nvim_buf_set_keymap(bufnr, "n", "js", "lua require('jc.jdtls').generate_accessor('s')", opts) - vim.api.nvim_buf_set_keymap(bufnr, "n", "jg", "lua require('jc.jdtls').generate_accessor('g')", opts) + vim.api.nvim_buf_set_keymap(bufnr, "n", prefix .. "A", "lua require('jc.jdtls').generate_accessors()", opts) + vim.api.nvim_buf_set_keymap( + bufnr, + "n", + prefix .. "s", + "lua require('jc.jdtls').generate_accessor('s')", + opts + ) + vim.api.nvim_buf_set_keymap( + bufnr, + "n", + prefix .. "g", + "lua require('jc.jdtls').generate_accessor('g')", + opts + ) vim.api.nvim_buf_set_keymap( bufnr, "n", @@ -40,14 +59,14 @@ function M.install_mappings(bufnr) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jc", + prefix .. "c", "lua require('jc.jdtls').generate_constructor(nil, nil, {default = false})", opts ) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jcc", + prefix .. "cc", "lua require('jc.jdtls').generate_constructor(nil, nil, {default = true})", opts ) @@ -55,7 +74,7 @@ function M.install_mappings(bufnr) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jm", + prefix .. "m", "lua require('jc.jdtls').generate_abstractMethods()", opts ) @@ -63,7 +82,7 @@ function M.install_mappings(bufnr) vim.api.nvim_buf_set_keymap( bufnr, "n", - "jn", + prefix .. "n", "lua require('jc.class_generator').generate_class()", opts ) @@ -72,7 +91,7 @@ function M.install_mappings(bufnr) vim.api.nvim_buf_set_keymap( bufnr, "v", - "jre", + prefix .. "re", "lua require('jdtls').extract_variable(true)", opts ) @@ -80,7 +99,7 @@ function M.install_mappings(bufnr) vim.api.nvim_buf_set_keymap( bufnr, "v", - "jrm", + prefix .. "rm", "lua require('jdtls').extract_method(true)", opts ) diff --git a/lua/jc/jdtls.lua b/lua/jc/jdtls.lua index 4b50645..b32281c 100644 --- a/lua/jc/jdtls.lua +++ b/lua/jc/jdtls.lua @@ -100,20 +100,30 @@ function M.generate_accessors(fields) end function M.generate_abstractMethods() + local curbuf = vim.api.nvim_get_current_buf() local diagnostics = {} + local line = 0 for _, diagnostic in ipairs(vim.diagnostic.get(0)) do if diagnostic.code == "67109264" then - diagnostic.range = { - start = { - character = diagnostic.col, - line = diagnostic.lnum, - }, - ["end"] = { - character = diagnostic.end_col, - line = diagnostic.end_lnum, + if line == 0 then + line = diagnostic.lnum + end + table.insert(diagnostics, { + code = diagnostic.code, + message = diagnostic.message, + severity = 1, + source = "Java", + range = { + start = { + character = diagnostic.col, + line = diagnostic.lnum, + }, + ["end"] = { + character = diagnostic.end_col, + line = diagnostic.end_lnum, + }, }, - } - table.insert(diagnostics, diagnostic) + }) end end if diagnostics then @@ -121,7 +131,18 @@ function M.generate_abstractMethods() params.context = { diagnostics = diagnostics, } - vim.lsp.buf_request(0, "textDocument/codeAction", params, function(err, actions) + params.range = { + start = { + character = 0, + line = line, + }, + ["end"] = { + character = 0, + line = line, + }, + } + vim.notify(vim.print(params), vim.log.levels.DEBUG) + vim.lsp.buf_request(curbuf, "textDocument/codeAction", params, function(err, actions) if actions then local add_method_action = nil for _, action in ipairs(actions) do @@ -131,7 +152,8 @@ function M.generate_abstractMethods() end end if add_method_action then - vim.lsp.buf_request(0, "codeAction/resolve", add_method_action, apply_edit) + vim.notify(vim.print(add_method_action), vim.log.levels.DEBUG) + vim.lsp.buf_request(curbuf, "codeAction/resolve", add_method_action, apply_edit) else vim.notify("No action found", vim.log.levels.INFO) end diff --git a/lua/jc/lsp.lua b/lua/jc/lsp.lua index 753de7b..ea7b973 100644 --- a/lua/jc/lsp.lua +++ b/lua/jc/lsp.lua @@ -3,12 +3,12 @@ local chains = require("jc.chains")() local M = {} -function M.on_attach(_, bufnr) - config.initialize_configuration(bufnr) +function M.on_attach(conf, _, bufnr) + config.initialize_configuration(conf, bufnr) end function M.executeCommand(command, callback, on_failure) - local clients = vim.lsp.buf_get_clients() + local clients = vim.lsp.get_clients() local capableClient = nil for _, client in pairs(clients) do @@ -41,7 +41,7 @@ function M.executeCommand(command, callback, on_failure) end function M.get_jdtls_client() - local clients = vim.lsp.get_active_clients() + local clients = vim.lsp.get_clients() for _, client in ipairs(clients) do if client.name == "jdtls" then return client diff --git a/lua/jc/server.lua b/lua/jc/server.lua index ac5eda8..942dc6e 100644 --- a/lua/jc/server.lua +++ b/lua/jc/server.lua @@ -3,23 +3,29 @@ local path = require("jc.path") local M = {} local function build_plugin(name) - local mvn_exec = { "mvn", "-Dmaven.javadoc.skip=true", "-Dmaven.test.skip=true", "-f", path.get_vendor_dir() .. name, "clean", "install" } + local mvn_exec = { + "mvn", + "-Dmaven.javadoc.skip=true", + "-Dmaven.test.skip=true", + "-f", + path.get_vendor_dir() .. name, + "clean", + "install", + } local env = vim.loop.os_environ() env["LC_CTYPE"] = "C" - Job - :new( - { exec = mvn_exec, title = "COMPILING " .. name .. " plugin" }, - { env = env, cwd = path.get_vendor_dir() .. name }, - function(_) - vim.notify(name .. " successfully installed") - M.jdtls_setup(M.config) - end, - function(job, ec) - job.output:append("JC ERROR: couldn't build " .. name .. " plugin. Exit code: " .. ec) - job.output:append("JC ERROR: consider to report an issue, please.") - end - ) - :execute() + Job:new( + { exec = mvn_exec, title = "COMPILING " .. name .. " plugin" }, + { env = env, cwd = path.get_vendor_dir() .. name }, + function(_) + vim.notify(name .. " successfully installed") + M.jdtls_setup(M.config) + end, + function(job, ec) + job.output:append("JC ERROR: couldn't build " .. name .. " plugin. Exit code: " .. ec) + job.output:append("JC ERROR: consider to report an issue, please.") + end + ):execute() end local function install_from_git(command, name, url) @@ -42,55 +48,60 @@ local function install_from_git(command, name, url) return path.get_vendor_dir() end - Job - :new( - { exec = git_exec(), title = command:upper() .. " " .. name .. " repository" }, - { env = vim.loop.os_environ(), cwd = cwd() }, - function(_) - vim.defer_fn(function() - build_plugin(name) - end, 0) - end, - function(job, exit_code) - if exit_code == 128 then - install_from_git("pull", name, url) - else - job.output:append("JC ERROR: couldn't clone " .. name .. " plugin. Exit code: " .. exit_code) - job.output:append("JC ERROR: consider to report an issue, please.") - end + Job:new( + { exec = git_exec(), title = command:upper() .. " " .. name .. " repository" }, + { env = vim.loop.os_environ(), cwd = cwd() }, + function(_) + vim.defer_fn(function() + build_plugin(name) + end, 0) + end, + function(job, exit_code) + if exit_code == 128 then + install_from_git("pull", name, url) + else + job.output:append("JC ERROR: couldn't clone " .. name .. " plugin. Exit code: " .. exit_code) + job.output:append("JC ERROR: consider to report an issue, please.") end - ) - :execute() + end + ):execute() end local function download_jdtls() - local ok, installer = pcall(require, "nvim-lsp-installer") - assert(ok, "nvim-lsp-installer is not installed") - - local servers = require("nvim-lsp-installer.servers") + local ok, registry = pcall(require, "mason-registry") + assert(ok, "mason is not installed") - vim.notify("Installing JDTLS language server...", vim.log.levels.INFO) - installer.install("jdtls") + local mason = require("mason.ui.instance") + local p = registry.get_package("jdtls") + if p then + vim.notify("Installing JDTLS language server...", vim.log.levels.INFO) + mason.window.open() + p:install() + end - local timer = vim.loop.new_timer() - timer:start(2000, 1500, function() - if servers.is_server_installed("jdtls") then - timer:close() - installer.info_window.close() - vim.defer_fn(function() - M.jdtls_setup(M.config) - vim.notify("JDTLS language server installed, completion should work now", vim.log.levels.INFO) - end, 100) - end - end) + local timer = vim.uv.new_timer() + timer:start( + 2000, + 1500, + vim.schedule_wrap(function() + if registry.is_installed("jdtls") then + timer:close() + mason.window.close() + vim.defer_fn(function() + M.jdtls_setup(M.config) + vim.notify("JDTLS language server installed, completion should work now", vim.log.levels.INFO) + end, 100) + end + end) + ) end local function resolve_jdtls() - local ok, servers = pcall(require, "nvim-lsp-installer.servers") - assert(ok, "nvim-lsp-installer is not installed") + local ok, registry = pcall(require, "mason-registry") + assert(ok, "mason is not installed") - if servers.is_server_installed("jdtls") then - local jdtls_path = servers.get_server_install_path("jdtls") + if registry.is_installed("jdtls") then + local jdtls_path = registry.get_package("jdtls"):get_install_path() return { jar = vim.fn.expand(jdtls_path .. "/plugins/org.eclipse.equinox.launcher_*.jar"), config = vim.fn.expand(jdtls_path .. "/config_" .. vim.g["utils#OS"]), @@ -108,9 +119,8 @@ local function resolve_java_debug() ) local skip_flag = path.get_workspace_dir() .. ".skip-java-debug" if vim.fn.filereadable(java_debug) == 0 and vim.fn.filereadable(skip_flag) == 0 then - local answer = vim.fn.input( - "No java debug plugin installed. Would you like to install?\n1: Yes\n2: No\nYour answer: " - ) + local answer = + vim.fn.input("No java debug plugin installed. Would you like to install?\n1: Yes\n2: No\nYour answer: ") if answer == "1" then install_from_git(nil, "java-debug", "https://github.com/microsoft/java-debug/") elseif answer == "2" then @@ -193,33 +203,72 @@ local function lspconfig_setup(paths) paths.java_debug, } - require("lspconfig").jdtls.setup({ - name = "jdtls", - root_dir = function() - return vim.fn.getcwd() - end, - on_attach = M.config.jc_on_attach, - cmd = cmd, - settings = settings, - init_options = { - bundles = bundles, - extendedClientCapabilities = { - progressReportProvider = true, - classFileContentsSupport = true, - generateToStringPromptSupport = true, - hashCodeEqualsPromptSupport = true, - advancedExtractRefactoringSupport = true, - advancedOrganizeImportsSupport = true, - generateConstructorsPromptSupport = true, - generateDelegateMethodsPromptSupport = true, - moveRefactoringSupport = true, - overrideMethodsPromptSupport = true, - inferSelectionSupport = { "extractMethod", "extractVariable", "extractConstant" }, + vim.api.nvim_create_autocmd("LspAttach", { + callback = M.config.jc_on_attach, + }) + + local caps = vim.tbl_deep_extend( + "keep", + require("cmp_nvim_lsp").default_capabilities() or nil, + vim.lsp.protocol.make_client_capabilities(), + { + textDocument = { + codeAction = { + codeActionLiteralSupport = { + codeActionKind = { + valueSet = { + "textDocument", + "codeAction", + "codeActionLiteralSupport", + "codeActionKind", + "valueSet", + }, + }, + }, + }, }, - workspace = path.get_project_dirs().workspace_dir, - }, + } + ) + + local function attach() + require("jdtls").start_or_attach({ + name = "jdtls", + root_dir = vim.fn.getcwd(), + on_attach = M.config.jc_on_attach, + cmd = cmd, + settings = settings, + init_options = { + bundles = bundles, + extendedClientCapabilities = { + classFileContentsSupport = true, + generateToStringPromptSupport = true, + hashCodeEqualsPromptSupport = true, + advancedExtractRefactoringSupport = true, + advancedOrganizeImportsSupport = true, + generateConstructorsPromptSupport = true, + generateDelegateMethodsPromptSupport = true, + moveRefactoringSupport = true, + overrideMethodsPromptSupport = true, + executeClientCommandSupport = true, + inferSelectionSupport = { + "extractMethod", + "extractVariable", + "extractConstant", + "extractVariableAllOccurrence", + }, + }, + capabilities = caps, + workspace = path.get_project_dirs().workspace_dir, + }, + }) + end + + vim.api.nvim_create_autocmd("FileType", { + pattern = { "java" }, + callback = attach, }) - require("lspconfig.configs")["jdtls"].launch() + + attach() end function M.jdtls_setup(config)