diff --git a/ftplugin/java.lua b/ftplugin/java.lua new file mode 100644 index 00000000..0e7ef28b --- /dev/null +++ b/ftplugin/java.lua @@ -0,0 +1,271 @@ +local java_cmds = vim.api.nvim_create_augroup('java_cmds', { clear = true }) +local cache_vars = {} + +-- Here you can add files/folders that you use at +-- the root of your project. `nvim-jdtls` will use +-- these to find the path to your project source code. +local root_files = { + '.git', + + --- here are more examples files that may or + --- may not work as root files, according to some guy on the internet + -- 'mvnw', + -- 'gradlew', + -- 'pom.xml', + -- 'build.gradle', +} + +local features = { + -- change this to `true` to enable codelens + codelens = false, + + -- change this to `true` if you have `nvim-dap`, + -- `java-test` and `java-debug-adapter` installed + debugger = false, +} + +local function get_jdtls_paths() + if cache_vars.paths then + return cache_vars.paths + end + + local path = {} + + path.data_dir = vim.fn.stdpath 'cache' .. '/nvim-jdtls' + + local jdtls_install = require('mason-registry').get_package('jdtls'):get_install_path() + + path.java_agent = jdtls_install .. '/lombok.jar' + path.launcher_jar = vim.fn.glob(jdtls_install .. '/plugins/org.eclipse.equinox.launcher_*.jar') + + if vim.fn.has 'mac' == 1 then + path.platform_config = jdtls_install .. '/config_mac' + elseif vim.fn.has 'unix' == 1 then + path.platform_config = jdtls_install .. '/config_linux' + elseif vim.fn.has 'win32' == 1 then + path.platform_config = jdtls_install .. '/config_win' + end + + path.bundles = {} + + --- + -- Include java-test bundle if present + --- + local java_test_path = require('mason-registry').get_package('java-test'):get_install_path() + + local java_test_bundle = vim.split(vim.fn.glob(java_test_path .. '/extension/server/*.jar'), '\n') + + if java_test_bundle[1] ~= '' then + vim.list_extend(path.bundles, java_test_bundle) + end + + --- + -- Include java-debug-adapter bundle if present + --- + local java_debug_path = require('mason-registry').get_package('java-debug-adapter'):get_install_path() + + local java_debug_bundle = vim.split(vim.fn.glob(java_debug_path .. '/extension/server/com.microsoft.java.debug.plugin-*.jar'), '\n') + + if java_debug_bundle[1] ~= '' then + vim.list_extend(path.bundles, java_debug_bundle) + end + + --- + -- Useful if you're starting jdtls with a Java version that's + -- different from the one the project uses. + --- + path.runtimes = { + -- Note: the field `name` must be a valid `ExecutionEnvironment`, + -- you can find the list here: + -- https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request + { + name = 'JavaSE-21', + path = vim.fn.expand '~/.sdkman/candidates/java/21.0.1-amzn', + }, + } + + cache_vars.paths = path + + return path +end + +local function enable_codelens(bufnr) + pcall(vim.lsp.codelens.refresh) + + vim.api.nvim_create_autocmd('BufWritePost', { + buffer = bufnr, + group = java_cmds, + desc = 'refresh codelens', + callback = function() + pcall(vim.lsp.codelens.refresh) + end, + }) +end + +local function enable_debugger(bufnr) + require('jdtls').setup_dap { hotcodereplace = 'auto' } + require('jdtls.dap').setup_dap_main_class_configs() + + local opts = { buffer = bufnr } + vim.keymap.set('n', 'df', "lua require('jdtls').test_class()", opts) + vim.keymap.set('n', 'dn', "lua require('jdtls').test_nearest_method()", opts) +end + +local function jdtls_on_attach(client, bufnr) + if features.debugger then + enable_debugger(bufnr) + end + + if features.codelens then + enable_codelens(bufnr) + end + + -- The following mappings are based on the suggested usage of nvim-jdtls + -- https://github.com/mfussenegger/nvim-jdtls#usage + + local opts = { buffer = bufnr } + vim.keymap.set('n', '', "lua require('jdtls').organize_imports()", opts) + vim.keymap.set('n', 'crv', "lua require('jdtls').extract_variable()", opts) + vim.keymap.set('x', 'crv', "lua require('jdtls').extract_variable(true)", opts) + vim.keymap.set('n', 'crc', "lua require('jdtls').extract_constant()", opts) + vim.keymap.set('x', 'crc', "lua require('jdtls').extract_constant(true)", opts) + vim.keymap.set('x', 'crm', "lua require('jdtls').extract_method(true)", opts) +end + +local function jdtls_setup(event) + local jdtls = require 'jdtls' + + local path = get_jdtls_paths() + local data_dir = path.data_dir .. '/' .. vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t') + + if cache_vars.capabilities == nil then + jdtls.extendedClientCapabilities.resolveAdditionalTextEditsSupport = true + + local ok_cmp, cmp_lsp = pcall(require, 'cmp_nvim_lsp') + cache_vars.capabilities = vim.tbl_deep_extend('force', vim.lsp.protocol.make_client_capabilities(), ok_cmp and cmp_lsp.default_capabilities() or {}) + end + + -- The command that starts the language server + -- See: https://github.com/eclipse/eclipse.jdt.ls#running-from-the-command-line + local 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:' .. path.java_agent, + '-Xms1g', + '--add-modules=ALL-SYSTEM', + '--add-opens', + 'java.base/java.util=ALL-UNNAMED', + '--add-opens', + 'java.base/java.lang=ALL-UNNAMED', + + -- 💀 + '-jar', + path.launcher_jar, + + -- 💀 + '-configuration', + path.platform_config, + + -- 💀 + '-data', + data_dir, + } + + local home = os.getenv 'HOME' + local lsp_settings = { + java = { + -- jdt = { + -- ls = { + -- vmargs = "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx1G -Xms100m" + -- } + -- }, + eclipse = { + downloadSources = true, + }, + configuration = { + updateBuildConfiguration = 'interactive', + runtimes = path.runtimes, + }, + maven = { + downloadSources = true, + }, + implementationsCodeLens = { + enabled = true, + }, + referencesCodeLens = { + enabled = true, + }, + -- inlayHints = { + -- parameterNames = { + -- enabled = 'all' -- literals, all, none + -- } + -- }, + format = { + enabled = true, + settings = { + url = home .. '/.config/nvim/clavisit-eclipse-code-formatter.xml', + profile = 'ClavisJavaStyle', + }, + }, + }, + signatureHelp = { + 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.*', + }, + }, + contentProvider = { + preferred = 'fernflower', + }, + extendedClientCapabilities = jdtls.extendedClientCapabilities, + sources = { + organizeImports = { + starThreshold = 9999, + staticStarThreshold = 9999, + }, + }, + codeGeneration = { + toString = { + template = '${object.className}{${member.name()}=${member.value}, ${otherMembers}}', + }, + useBlocks = true, + }, + } + + -- This starts a new client & server, + -- or attaches to an existing client & server depending on the `root_dir`. + jdtls.start_or_attach { + cmd = cmd, + settings = lsp_settings, + on_attach = jdtls_on_attach, + capabilities = cache_vars.capabilities, + root_dir = jdtls.setup.find_root(root_files), + flags = { + allow_incremental_sync = true, + }, + init_options = { + bundles = path.bundles, + }, + } +end + +vim.api.nvim_create_autocmd('FileType', { + group = java_cmds, + pattern = { 'java' }, + desc = 'Setup jdtls', + callback = jdtls_setup, +}) diff --git a/lua/custom/plugins/cmake-tools.lua b/lua/custom/plugins/cmake-tools.lua new file mode 100644 index 00000000..7964cf7c --- /dev/null +++ b/lua/custom/plugins/cmake-tools.lua @@ -0,0 +1,6 @@ +return { + 'Civitasv/cmake-tools.nvim', + config = function() + require('cmake-tools').setup {} + end, +} diff --git a/lua/custom/plugins/nvim-jdtls.lua b/lua/custom/plugins/nvim-jdtls.lua new file mode 100644 index 00000000..4ea3df01 --- /dev/null +++ b/lua/custom/plugins/nvim-jdtls.lua @@ -0,0 +1 @@ +return { 'mfussenegger/nvim-jdtls' } diff --git a/lua/kickstart/plugins/debug.lua b/lua/kickstart/plugins/debug.lua index 9a185846..4b93c42c 100644 --- a/lua/kickstart/plugins/debug.lua +++ b/lua/kickstart/plugins/debug.lua @@ -44,6 +44,8 @@ return { 'delve', 'netcoredbg', 'codelldb', + 'java-debug-adapter', + 'java-test', }, } diff --git a/lua/plugins.lua b/lua/plugins.lua index 0035bb1d..e95df6b8 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -360,6 +360,38 @@ require('lazy').setup({ -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ local servers = { tsserver = {}, + stylelint_lsp = { + filetypes = { 'css', 'scss' }, + root_dir = require('lspconfig').util.root_pattern('package.json', '.git'), + settings = { + stylelintplus = { + autoFixOnFormat = true, + autoFixOnSave = true, + }, + }, + on_attach = function(client) + client.server_capabilities.document_formatting = false + end, + }, + eslint = { + bin = 'eslint', -- or `eslint_d` + code_actions = { + enable = true, + apply_on_save = { + enable = true, + types = { 'directive', 'problem', 'suggestion', 'layout' }, + }, + disable_rule_comment = { + enable = true, + location = 'separate_line', -- or `same_line` + }, + }, + diagnostics = { + enable = true, + report_unused_disable_directives = false, + run_on = 'type', -- or `save` + }, + }, csharp_ls = {}, netcoredbg = {}, clangd = {}, @@ -394,9 +426,12 @@ require('lazy').setup({ local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { 'stylua', -- Used to format Lua code + 'eslint_d', + 'stylelint', 'clang-format', 'lua_ls', 'omnisharp', + 'jdtls', }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } @@ -442,6 +477,10 @@ require('lazy').setup({ end, formatters_by_ft = { lua = { 'stylua' }, + typescript = { 'prettier' }, + javascript = { 'prettier' }, + json = { 'prettier' }, + html = { 'prettier' }, -- Conform can also run multiple formatters sequentially -- python = { "isort", "black" }, -- diff --git a/lua/remap.lua b/lua/remap.lua index 18afc4d4..713636a1 100644 --- a/lua/remap.lua +++ b/lua/remap.lua @@ -20,12 +20,6 @@ vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagn -- or just use to exit terminal mode vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) --- Disable arrow keys in normal mode -vim.keymap.set('n', '', 'echo "Use h to move!!"') -vim.keymap.set('n', '', 'echo "Use l to move!!"') -vim.keymap.set('n', '', 'echo "Use k to move!!"') -vim.keymap.set('n', '', 'echo "Use j to move!!"') - -- Enable moving highlighted lines vim.keymap.set('v', 'J', ":m '>+1gv=gv") vim.keymap.set('v', 'K', ":m '<-2gv=gv")