Skip to content

Instantly share code, notes, and snippets.

@IlyasYOY
Last active July 26, 2023 12:39
Show Gist options
  • Save IlyasYOY/f0105354306b5b37fa2d6805512155d0 to your computer and use it in GitHub Desktop.
Save IlyasYOY/f0105354306b5b37fa2d6805512155d0 to your computer and use it in GitHub Desktop.
Simple JDTLS config for NeoVim
local lazypath = vim.fn.stdpath "data" .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system {
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
}
end
vim.opt.rtp:prepend(lazypath)
vim.g.mapleader = " "
vim.cmd "source ~/.vimrc"
vim.g.netrw_banner = 0 -- Now we won't have bloated top of the window
vim.g.netrw_liststyle = 3 -- Now it will be a tree view
vim.g.netrw_bufsettings = "nu nobl"
vim.opt.spelllang = "ru_ru,en_us"
vim.opt.spellfile = vim.fn.expand "~/.config/nvim/spell/custom.utf-8.add"
vim.opt.listchars = "eol:¬,tab:>·,trail:~,extends:>,precedes:<"
vim.opt.list = true
-- Helpers
local function describe(x, desc)
return vim.tbl_extend("force", x, { desc = desc })
end
local function on_attach(client, bufnr)
-- Enable completion triggered by <c-x><c-o>
vim.api.nvim_buf_set_option(bufnr, "omnifunc", "v:lua.vim.lsp.omnifunc")
-- See `:help vim.lsp.*` for documentation on any of the below functions
local bufopts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set(
"n",
"<leader>s",
vim.lsp.buf.workspace_symbol,
describe(bufopts, "Show Workspace Symbols")
)
vim.keymap.set(
"n",
"gD",
vim.lsp.buf.declaration,
describe(bufopts, "go to Declarations")
)
vim.keymap.set(
"n",
"gd",
vim.lsp.buf.definition,
describe(bufopts, "go to definitions")
)
vim.keymap.set(
"n",
"gr",
vim.lsp.buf.references,
describe(bufopts, "go to references")
)
vim.keymap.set(
"n",
"gi",
vim.lsp.buf.implementation,
describe(bufopts, "go to implementations")
)
vim.keymap.set(
{ "n", "i" },
"<C-s>",
vim.lsp.buf.signature_help,
describe(bufopts, "Help with signature")
)
vim.keymap.set(
"n",
"<space>wa",
vim.lsp.buf.add_workspace_folder,
describe(bufopts, "workspace add folder")
)
vim.keymap.set(
"n",
"<space>wr",
vim.lsp.buf.remove_workspace_folder,
describe(bufopts, "workspace remove folder")
)
vim.keymap.set("n", "<space>wl", function()
vim.notify(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, describe(bufopts, "workspace list folders"))
vim.keymap.set(
"n",
"<space>rn",
vim.lsp.buf.rename,
describe(bufopts, "rename symbol under the cursor")
)
end
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap = true, silent = true }
vim.keymap.set(
"n",
"<leader>d",
vim.diagnostic.open_float,
describe(opts, "diagnostics")
)
vim.keymap.set(
"n",
"[d",
vim.diagnostic.goto_prev,
describe(opts, "Previous diagostics")
)
vim.keymap.set(
"n",
"]d",
vim.diagnostic.goto_next,
describe(opts, "Next diagnostics")
)
vim.keymap.set(
"n",
"<leader>ld",
vim.diagnostic.setloclist,
describe(opts, "Put diagnostics to quickfix list")
)
require("lazy").setup({
"IlyasYOY/coredor.nvim",
"nvim-lua/plenary.nvim",
{
"nvim-treesitter/nvim-treesitter",
build = function()
local ts_update = require("nvim-treesitter.install").update {
with_sync = true,
}
ts_update()
end,
config = function()
local ts_config = require "nvim-treesitter.configs"
ts_config.setup {
ensure_installed = {
"vim",
"lua",
"java",
},
sync_install = false,
auto_install = false,
highlight = {
enable = true,
disable = function(lang, buf)
local max_filesize = 100 * 1024 -- 100 KB
local ok, stats = pcall(
vim.loop.fs_stat,
vim.api.nvim_buf_get_name(buf)
)
if ok and stats and stats.size > max_filesize then
return true
end
end,
additional_vim_regex_highlighting = false,
},
}
end,
},
{
"williamboman/mason.nvim",
config = function()
local mason = require "mason"
mason.setup {
ui = {
icons = {
package_installed = "✓",
package_pending = "➜",
package_uninstalled = "✗",
},
},
}
end,
},
{
"williamboman/mason-lspconfig.nvim",
config = function()
require("mason-lspconfig").setup {
ensure_installed = {
"jdtls",
"lua_ls",
"bashls",
},
automatic_installation = true,
}
end,
},
{
"mfussenegger/nvim-jdtls",
lazy = true,
ft = { "java" },
},
{
"neovim/nvim-lspconfig",
config = function()
local function setup_generic()
local lspconfig = require "lspconfig"
local generic_servers = {
"bashls",
}
for _, client in ipairs(generic_servers) do
lspconfig[client].setup {
on_attach = on_attach,
}
end
end
local function setup_lua()
local lspconfig = require "lspconfig"
lspconfig.lua_ls.setup {
on_attach = on_attach,
}
end
setup_generic()
setup_lua()
-- NOTE: This mapping may be used by null-ls in any given file.
local bufopts = { noremap = true, silent = true }
vim.keymap.set({ "n", "v" }, "<space>oc", function()
vim.lsp.buf.format { async = true }
end, describe(bufopts, "organize code"))
vim.keymap.set(
{ "n", "v" },
"<space>a",
vim.lsp.buf.code_action,
describe(bufopts, "Perform code action")
)
vim.keymap.set(
"n",
"<leader>k",
vim.lsp.buf.hover,
describe(bufopts, "show hover")
)
end,
},
{
"ellisonleao/gruvbox.nvim",
lazy = false,
config = function()
vim.cmd.colorscheme "gruvbox"
end,
},
}, {
change_detection = {
enabled = false,
notify = false,
},
})
vim.api.nvim_create_augroup("NvimJdtlsOnJava", { clear = true })
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
pattern = "*.java",
callback = function()
local Path = require "plenary.path"
local coredor = require "coredor"
local jdtls = require "jdtls"
local function resolve_dotfiles_plenary_path()
local path_from_env = vim.fn.environ().ILYASYOY_DOTFILES_DIR
return Path:new(path_from_env)
end
local function resolve_realative_to_dotfiles_dir(path)
local plenary_path = resolve_dotfiles_plenary_path()
return (plenary_path / path):expand()
end
local function get_install_path_for(package)
return require("mason-registry")
.get_package(package)
:get_install_path()
end
-- loads jdks from sdkman.
---@param version string java version to search for
-- NOTE: This requires java to be installed using sdkman.
local function get_java_dir(version)
local sdkman_dir = Path.path.home .. "/.sdkman/candidates/java/"
local java_dirs = vim.fn.readdir(sdkman_dir, function(file)
if coredor.string_has_prefix(file, version .. ".", true) then
return 1
end
end)
local java_dir = java_dirs[1]
if not java_dir then
error(string.format("No %s java version was found", version))
end
return sdkman_dir .. java_dir
end
local project_name =
vim.fn.fnamemodify(vim.fn.getcwd(), ":p:gs?/?-?:s?~-??")
local workspace_dir = Path.path.home
.. "/Projects/eclipse-java/"
.. project_name
local config = {
cmd = {
"jdtls",
"-data",
workspace_dir,
cmd = {
"jdtls",
"-data",
workspace_dir,
"--jvm-arg=-XX:+UseParallelGC",
"--jvm-arg=-XX:GCTimeRatio=4",
"--jvm-arg=-XX:AdaptiveSizePolicyWeight=90",
"--jvm-arg=-Dsun.zip.disableMemoryMapping=true",
"--jvm-arg=-Xmx1G",
"--jvm-arg=-Xms500m",
"--jvm-arg=-Xlog:disable",
"--jvm-arg=-javaagent:"
.. get_install_path_for "jdtls"
.. "/lombok.jar",
},
root_dir = require("jdtls.setup").find_root { "mvnw", "gradlew" },
settings = {
java = {
redhat = {
telemetry = {
enabled = false,
},
},
maven = {
downloadSources = true,
},
format = {
settings = {
url = resolve_realative_to_dotfiles_dir "config/eclipse-java-google-style.xml",
profile = "GoogleStyle",
},
},
compile = {
nullAnalysis = {
nonnull = {
"lombok.NonNull",
"javax.annotation.Nonnull",
"org.eclipse.jdt.annotation.NonNull",
"org.springframework.lang.NonNull",
},
},
},
eclipse = {
downloadSources = true,
},
completion = {
-- doesn't seem to work now with cmp.
chain = {
enabled = false,
},
guessMethodArguments = "off",
favouriteStaticMembers = {
"org.junit.jupiter.api.Assertions.*",
"org.junit.jupiter.api.Assumptions.*",
"org.mockito.Mockito.*",
"java.util.Objects.*",
},
},
configuration = {
runtimes = {
{
name = "JavaSE-1.8",
path = get_java_dir "8",
},
{
name = "JavaSE-11",
path = get_java_dir "11",
},
{
name = "JavaSE-17",
path = get_java_dir "17",
},
},
},
},
},
on_attach = function(client, bufnr)
require("jdtls").setup_dap()
require("jdtls.setup").add_commands()
vim.keymap.set("n", "<leader>oi", function()
jdtls.organize_imports()
end, {
desc = "organize imports",
})
vim.keymap.set("n", "<leader>oa", function()
jdtls.organize_imports()
vim.lsp.buf.format()
end, {
desc = "organize all",
})
vim.keymap.set("v", "<leader>jev", function()
jdtls.extract_variable(true)
end, {
desc = "java extract selected to variable",
noremap = true,
})
vim.keymap.set("n", "<leader>jev", function()
jdtls.extract_variable()
end, {
desc = "java extract variable",
noremap = true,
})
vim.keymap.set("v", "<leader>jeV", function()
jdtls.extract_variable_all(true)
end, {
desc = "java extract all selected to variable",
noremap = true,
})
vim.keymap.set("n", "<leader>jeV", function()
jdtls.extract_variable_all()
end, {
desc = "java extract all to variable",
noremap = true,
})
vim.keymap.set("n", "<leader>jec", function()
jdtls.extract_constant()
end, {
desc = "java extract constant",
noremap = true,
})
vim.keymap.set("v", "<leader>jec", function()
jdtls.extract_constant(true)
end, {
desc = "java extract selected to constant",
noremap = true,
})
vim.keymap.set("n", "<leader>jem", function()
jdtls.extract_method()
end, {
desc = "java extract method",
noremap = true,
})
vim.keymap.set("v", "<leader>jem", function()
jdtls.extract_method(true)
end, {
desc = "java extract selected to method",
noremap = true,
})
vim.keymap.set("n", "<leader>ot", function()
local plugin = require "jdtls.tests"
plugin.goto_subjects()
end, {
desc = "java open test",
noremap = true,
})
vim.keymap.set("n", "<leader>ct", function()
local plugin = require "jdtls.tests"
plugin.generate()
end, {
desc = "java create test",
noremap = true,
})
vim.keymap.set("n", "<leader>jdm", function()
jdtls.test_nearest_method()
end, { desc = "java debug nearest test method" })
vim.keymap.set("n", "<leader>jdc", function()
jdtls.test_class()
end, { desc = "java debug nearest test class" })
vim.cmd [[ command! -buffer -nargs=? -complete=custom,v:lua.require'jdtls'._complete_compile JdtCompile lua require('jdtls').compile(<f-args>) ]]
vim.cmd [[ command! -buffer -nargs=? -complete=custom,v:lua.require'jdtls'._complete_set_runtime JdtSetRuntime lua require('jdtls').set_runtime(<f-args>) ]]
vim.cmd [[ command! -buffer JdtUpdateConfig lua require('jdtls').update_project_config() ]]
vim.cmd [[ command! -buffer JdtBytecode lua require('jdtls').javap() ]]
vim.cmd [[ command! -buffer JdtJol lua require('jdtls').jol() ]]
vim.cmd [[ command! -buffer JdtJshell lua require('jdtls').jshell() ]]
on_attach(client, bufnr)
end,
init_options = {
bundles = vim.tbl_flatten {
coredor.string_split(
vim.fn.glob(
get_install_path_for "java-debug-adapter"
.. "/extension/server/"
.. "com.microsoft.java.debug.plugin-*.jar",
1
),
"\n"
),
coredor.string_split(
vim.fn.glob(
get_install_path_for "java-test"
.. "/extension/server/"
.. "*.jar",
1
),
"\n"
),
},
},
}
jdtls.start_or_attach(config)
end,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment