diff --git a/symlinks/config/nvim/lua/esensar/init/plugins.lua b/symlinks/config/nvim/lua/esensar/init/plugins.lua index cca55d1..4b0214a 100644 --- a/symlinks/config/nvim/lua/esensar/init/plugins.lua +++ b/symlinks/config/nvim/lua/esensar/init/plugins.lua @@ -43,6 +43,7 @@ return require("lazy").setup({ -- Tools "direnv/direnv.vim", -- Integration with Direnv "nvim-neotest/neotest", -- Running tests from NeoVim + "nvim-neotest/nvim-nio", "nvim-neotest/neotest-plenary", "rouge8/neotest-rust", "nvim-neotest/neotest-vim-test", -- vim-test plugin for neotest @@ -56,7 +57,10 @@ return require("lazy").setup({ "https://codeberg.org/neovim-java/neovim-java-plugin-host", -- Host for Java plugins -- Snippets - "L3MON4D3/LuaSnip", -- snippets support + { + "L3MON4D3/LuaSnip", + build = "make install_jsregexp", + }, -- snippets support "rafamadriz/friendly-snippets", -- Collection of snippets "saadparwaiz1/cmp_luasnip", -- cmp snippets support diff --git a/symlinks/config/nvim/lua/esensar/lsp/completion.lua b/symlinks/config/nvim/lua/esensar/lsp/completion.lua index e6ebe9e..30c28dd 100644 --- a/symlinks/config/nvim/lua/esensar/lsp/completion.lua +++ b/symlinks/config/nvim/lua/esensar/lsp/completion.lua @@ -47,6 +47,13 @@ cmp.setup({ fallback() end end, { "i", "s" }), + [""] = cmp.mapping(function(fallback) + if luasnip.choice_active() then + luasnip.change_choice(1) + else + fallback() + end + end, { "i", "s" }), }, sources = { { name = "nvim_lsp" }, diff --git a/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua b/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua index d5d4088..f54196f 100644 --- a/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua +++ b/symlinks/config/nvim/lua/esensar/lsp/diagnostic.lua @@ -36,7 +36,7 @@ require("formatter").setup({ require("formatter.filetypes.zig").zigfmt, }, java = { - require("formatter.filetypes.java").clangformat, + require("esensar.lsp.formatters.clang-format-java"), }, godot = { require("esensar.lsp.formatters.gdformat"), diff --git a/symlinks/config/nvim/lua/esensar/lsp/formatters/clang-format-java.lua b/symlinks/config/nvim/lua/esensar/lsp/formatters/clang-format-java.lua new file mode 100644 index 0000000..709491f --- /dev/null +++ b/symlinks/config/nvim/lua/esensar/lsp/formatters/clang-format-java.lua @@ -0,0 +1,10 @@ +return function() + local java_clang_format = require("formatter.filetypes.java").clangformat() + for i = #java_clang_format.args, 1, -1 do + if java_clang_format.args[i]:find("--style", 1, true) == 1 then + table.remove(java_clang_format.args, i) + end + end + vim.list_extend(java_clang_format.args, { '--style="{BasedOnStyle: Google, IndentWidth: 4}"' }) + return java_clang_format +end diff --git a/symlinks/config/nvim/lua/esensar/lsp/jdtls_setup.lua b/symlinks/config/nvim/lua/esensar/lsp/jdtls_setup.lua index 5e2cfde..b0214d5 100644 --- a/symlinks/config/nvim/lua/esensar/lsp/jdtls_setup.lua +++ b/symlinks/config/nvim/lua/esensar/lsp/jdtls_setup.lua @@ -23,18 +23,26 @@ local function is_in_config_home(bufname) end function M.setup() - local installed_jdtls = { - } + local installed_jdtls = {} installed_jdtls.cmd = { "jdtls" } require("jdtls").setup_dap({ hotcoredeplace = "auto" }) - local config = vim.tbl_extend("force", installed_jdtls, { + local config = vim.tbl_deep_extend("force", installed_jdtls, { flags = { allow_incremental_sync = true, }, on_attach = common_config.on_attach, + capabilities = { + textDocument = { + completion = { + completionItem = { + snippetSupport = true, + }, + }, + }, + }, }) config.settings = { java = { diff --git a/symlinks/config/nvim/plugin/projectionist.lua b/symlinks/config/nvim/plugin/projectionist.lua index a918d88..22aa142 100644 --- a/symlinks/config/nvim/plugin/projectionist.lua +++ b/symlinks/config/nvim/plugin/projectionist.lua @@ -326,6 +326,9 @@ local java_project_config = { ["src/main/resources/*"] = { type = "resource", }, + ["src/main/resources/META-INF/MANIFEST.MF"] = { + type = "manifest", + }, ["src/test/resources/*"] = { type = "testresource", }, @@ -380,6 +383,36 @@ local kotlin_project_config = { }, } +local maven_project_config = { + ["*"] = { + start = "mvn package", + }, + ["pom.xml"] = { + type = "pom", + }, +} + +local gradle_project_config = { + ["*"] = { + start = "./gradlew assemble", + }, + ["build.gradle"] = { + type = "build", + }, + ["build.gradle.kts"] = { + type = "build", + }, + ["settings.gradle"] = { + type = "settings", + }, + ["gradle.properties"] = { + type = "properties", + }, + ["local.properties"] = { + type = "localproperties", + }, +} + local mint_config = { ["*"] = { start = "mint start", @@ -635,6 +668,8 @@ vim.g.projectionist_heuristics = { ["lua/"] = lua_vim_plugin_config, ["build.gradle|pom.xml"] = java_project_config, ["build.gradle|build.gradle.kts"] = kotlin_project_config, + ["build.gradle|build.gradle.kts|settings.gradle"] = gradle_project_config, + ["pom.xml"] = maven_project_config, ["mint.json"] = mint_config, ["shard.yml"] = crystal_config, ["Cargo.toml"] = rust_config, diff --git a/symlinks/config/nvim/plugin/snippets.lua b/symlinks/config/nvim/plugin/snippets.lua index 60f573c..19fb29c 100644 --- a/symlinks/config/nvim/plugin/snippets.lua +++ b/symlinks/config/nvim/plugin/snippets.lua @@ -1,6 +1,27 @@ local luasnip = require("luasnip") +local types = require("luasnip.util.types") local s = luasnip.snippet +local sn = luasnip.snippet_node local f = luasnip.function_node +local t = luasnip.text_node +local i = luasnip.insert_node +local c = luasnip.choice_node +local d = luasnip.dynamic_node + +luasnip.config.setup({ + ext_opts = { + [types.choiceNode] = { + active = { + virt_text = { { "●", "GruvboxOrange" } }, + }, + }, + [types.insertNode] = { + active = { + virt_text = { { "●", "GruvboxBlue" } }, + }, + }, + }, +}) luasnip.add_snippets("all", { s("date", { f(function(_, _) @@ -17,4 +38,122 @@ luasnip.add_snippets("all", { end) }), }) +-- Java snippets +local function jdocsnip(args, _, old_state) + -- !!! old_state is used to preserve user-input here. DON'T DO IT THAT WAY! + -- Using a restoreNode instead is much easier. + -- View this only as an example on how old_state functions. + local nodes = { + t({ "/**", " * " }), + i(1, "A short Description"), + t({ "", "" }), + } + + -- These will be merged with the snippet; that way, should the snippet be updated, + -- some user input eg. text can be referred to in the new snippet. + local param_nodes = {} + + if old_state then + nodes[2] = i(1, old_state.descr:get_text()) + end + param_nodes.descr = nodes[2] + + -- At least one param. + if string.find(args[2][1], ", ") then + vim.list_extend(nodes, { t({ " * ", "" }) }) + end + + local insert = 2 + for _, arg in ipairs(vim.split(args[2][1], ", ", true)) do + -- Get actual name parameter. + arg = vim.split(arg, " ", true)[2] + if arg then + local inode + -- if there was some text in this parameter, use it as static_text for this new snippet. + if old_state and old_state[arg] then + inode = i(insert, old_state["arg" .. arg]:get_text()) + else + inode = i(insert) + end + vim.list_extend(nodes, { t({ " * @param " .. arg .. " " }), inode, t({ "", "" }) }) + param_nodes["arg" .. arg] = inode + + insert = insert + 1 + end + end + + if args[1][1] ~= "void" then + local inode + if old_state and old_state.ret then + inode = i(insert, old_state.ret:get_text()) + else + inode = i(insert) + end + + vim.list_extend(nodes, { t({ " * ", " * @return " }), inode, t({ "", "" }) }) + param_nodes.ret = inode + insert = insert + 1 + end + + if vim.tbl_count(args[3]) ~= 1 then + local exc = string.gsub(args[3][2], " throws ", "") + local ins + if old_state and old_state.ex then + ins = i(insert, old_state.ex:get_text()) + else + ins = i(insert) + end + vim.list_extend(nodes, { t({ " * ", " * @throws " .. exc .. " " }), ins, t({ "", "" }) }) + param_nodes.ex = ins + insert = insert + 1 + end + + vim.list_extend(nodes, { t({ " */" }) }) + + local snip = sn(nil, nodes) + -- Error on attempting overwrite. + snip.old_state = param_nodes + return snip +end + +luasnip.add_snippets("java", { + -- Very long example for a java class. + s("fn", { + d(6, jdocsnip, { 2, 4, 5 }), + t({ "", "" }), + c(1, { + t("public "), + t("private "), + }), + c(2, { + t("void"), + t("String"), + t("char"), + t("int"), + t("double"), + t("boolean"), + i(nil, ""), + }), + t(" "), + i(3, "myFunc"), + t("("), + i(4), + t(")"), + c(5, { + t(""), + sn(nil, { + t({ "", " throws " }), + i(1), + }), + }), + t({ " {", "\t" }), + i(0), + t({ "", "}" }), + }), +}, { + key = "java", +}) + require("luasnip.loaders.from_vscode").lazy_load() + +require("luasnip").filetype_extend("java", { "javadoc", "java-tests" })