Java autocompletion for neovim
jc.nvim
jc.nvim โ successor of vim-javacomplete2 which use neovim's built-in LSP client and Eclipse JDT Language Server.
Read my blog post about it.
Main goal of this project is to migrate functionallty of jc2.
jc.nvim is a layer on top of an externally managed jdtls: it never starts the language server itself. Run jdtls with nvim-java, nvim-jdtls or nvim-lspconfig โ jc.nvim hooks into whatever jdtls client attaches and adds:
- organize imports with smart selection regular classes;
- generate code (
toString,hashCode,equals, constructors, accessors) with field selection; - add abstract methods to implementing class;
- debug attach/launch via nvim-dap or vimspector, with per-project host/port memory;
- decompiled
jdt://class contents view; - class creation methods from
jc2.
Installation
Requirements:
- a running
jdtlsmanaged by nvim-java, nvim-jdtls or lspconfig. The
extendedClientCapabilities (notably
executeClientCommandSupport and advancedOrganizeImportsSupport) โ
nvim-java and nvim-jdtls do this out of the box;
- for debug attach: the java-debug
init_options.bundles);
JCutilJollooks for the jol-cli jar in~/.m2and offers to download
require("jc.tools").jol_path).
Minimal setup using lazy.nvim (jdtls managed by nvim-java):
return {
{
"artur-shaik/jc.nvim",
ft = { "java" },
dependencies = {
"nvim-java/nvim-java",
},
opts = {
keys_prefix = "'j",
},
},
}
Configurations
All options go through setup(opts) (or the opts table of your plugin manager):
require("jc").setup({
keys_prefix = "<leader>j", -- prefix for the default mappings
default_mappings = true, -- install default mappings on attach
autoformatonsave = false, -- format java buffers on save
debug_backend = nil, -- "dap" | "vimspector" | nil (auto-detect)
basedir = nil, -- data dir, default ~/.local/share/jc.nvim
updateconfigonnewfile = true, -- refresh jdtls build path on new java files
on_attach = nil, -- function(client, bufnr) extra hook
})
The legacy g:jcdefaultmappings, g:jcautoformaton_save, g:jcdebugbackend and g:jc_basedir variables still work as a fallback when the corresponding option is not passed to setup.
A java file created in-editor isn't on jdtls' build path until the project configuration is refreshed, so go-to-definition returns nothing on it (while find-references still works off the search index). With updateconfigonnewfile (default true), jc.nvim detects such files and fires :JCutilUpdateConfig for them on first write automatically. Set it to false to refresh manually.
What it adds over plain nvim-jdtls
| Feature | nvim-jdtls | jc.nvim | |---|---|---| | Code generation (toString/equals/hashCode/constructors/accessors) | via code actions | dedicated commands and mappings with field selection | | Organize imports | code action | smart mode remembering preferred classes per project | | Debug attach | manual dap config | JCdebugAttach with per-project host/port memory, dap or vimspector | | Class creation from templates | โ | JCgenerateClass prompt DSL | | Extract refactorings | yes | built-in (java/inferSelection + java/getRefactorEdit) | | Classpath-aware javap/jshell/jol | yes | built-in |
:checkhealth jc verifies the setup; :help jc for full docs.
Commands
JCdebugAttachโ attach debugger (nvim-dap or vimspector, seedebug_backend);JCdebugLaunchโ launch debug session;JCdapAttach/JCvimspectorAttachโ attach using a specific backend;JCdebugWithConfigโ start debug session using predefined vimspector's configuration;JCimportsOrganizeSmartโ automatically organize imports using regular classes list;JCimportsOrganizeโ automatically organize imports choosing from available classes list;JCgenerateToStringโ choose fields and method to generatetoString;JCgenerateHashCodeAndEqualsโ choose fields to generatehashCodeandequals;JCgenerateAccessorsโ choose fields for accessors generation;JCgenerateAccessorGetterโ generate getter for a field;JCgenerateAccessorSetterโ generate setter for a field;JCgenerateAccessorSetterGetterโ generate getter and setter for a field;JCgenerateConstructorDefaultโ generate constructor with no arguments;JCgenerateConstructorโ choose fields for constructor;JCgenerateAbstractMethodsโ generate abstract methods;JCgenerateClassโ start class generation user input prompt;JCtoggleAutoformatโ enable/disable autoformat file on save;JCutilUpdateConfigโ re-read project configuration (pom/gradle);JCutilWipeWorkspaceโ delete the jdtls workspace (eclipse index) and restart the server;JCrefactorExtractVarโ extract variable;JCrefactorExtractMethodโ extract method (visual range);JCutilJshellโ execute java shell with project classpath;JCutilBytecodeโ extract bytecode for class (javap);JCutilJolโ analyze object layout scheme usingjol.jar.
Default mappings
Installed on jdtls attach when default_mappings is enabled. <p> is keys_prefix (default <leader>j).
| Mode | Keys | Action | |---|---|---| | n | <p>i | organize imports (smart) | | n | <p>I | organize imports (manual selection) | | i | <C-j>i | organize imports | | n | <p>ts | generate toString() | | n | <p>eq | generate hashCode() and equals() | | n | <p>A | generate accessors (field selection) | | n | <p>s / <p>g | generate setter / getter | | n | <leader>ja | generate getter and setter | | i | <C-j>s / <C-j>g / <C-j>a | accessor generation | | n | <p>c | generate constructor (field selection) | | n | <p>cc | generate default constructor | | n | <p>m, i <C-j>m | generate abstract methods | | n | <p>n | new class prompt | | n | <p>da / <p>dl | debug attach / launch | | v | <p>re / <p>rm | extract variable / method (selection) | | n | <p>re | extract variable (inferred at cursor) |
Class creation
Prompt scheme, for class creation:
template:[subdirectory]:/package.ClassName extends SuperClass implements Interface(String str, public Integer i):contructor:toString:equals
A: (optional) template - which will be used to create class boilerplate. Some existed templates: junit, interface, exception, servlet, etc;
B: (optional) subdirectory in which class will be put. For example: test, androidTest;
C: class name and package. With / will use backsearch for parent package to put in it. Without / put in relative package to current;
D: (optional) extends and implements classes will be automatically imported;
E: (optional) private str variable, and public i variable will be added to class;
F: (optional) contructor using all fields and toString will be created. Also hashCode and equals can be used.