Explore the docs Β»
Report Bug
Β·
Request Feature
Β·
Ask Question
Extensions for JetBrains' Kotlin Language Server (kotlin-lsp) support in Neovim
(>=0.11.0).
- Decompile and open class file contents using kotlin-lsp
decompilecommand - Export workspace to JSON using kotlin-lsp
exportWorkspacecommand - Organize imports with
KotlinOrganizeImportscommand - Format code with
KotlinFormatcommand (uses IntelliJ IDEA formatting) - Toggle diagnostic hints using the
KotlinHintsTogglecommand - Full support for LSP inlay hints with fine-grained configuration
- JDK version specification for symbol resolution
- Support for custom JVM arguments
- Support kotlin-lsp installation from Mason
- Navigate to package folders from package declarations (opens the folder view with oil.nvim using LSP "go to definition")
- Automatic per-project workspace isolation to prevent LSP conflicts and improve performance
- Use
KotlinCleanWorkspacecommand to clear cached indices for the current project
- Use
- Per-project LSP configuration via
.kotlin-lsp.luafile - Per-project LSP disabling via marker file
- Create a
.disable-kotlin-lspfile in the project root to prevent the Kotlin LSP from being registered
- Create a
Note
Version Requirements:
- Workspace isolation with the
--system-pathparameter requires kotlin-lsp v0.253.10629 or later. - Zero-dependencies platform-specific builds are supported -- no JDK required by default as the language server bundles its own (kotlin-lsp v261+ or later).
- Inlay hints require kotlin-lsp v261+ and are configured using the exact format from the VSCode extension.
- Code formatting and organize imports require kotlin-lsp v0.253+ with IntelliJ IDEA-based formatting support.
Install the plugin with your package manager:
Dependencies:
- mason.nvim - LSP installer
- mason-lspconfig.nvim - Mason LSP integration
- oil.nvim - File explorer for package navigation (used by "Go to Definition" on package declarations)
- trouble.nvim - Enhanced quickfix/location list UI (required for
:KotlinSymbolsand:KotlinWorkspaceSymbolscommands to display document outline and workspace symbols)
{
"AlexandrosAlexiou/kotlin.nvim",
ft = { "kotlin" },
dependencies = {
"mason.nvim",
"mason-lspconfig.nvim",
"oil.nvim",
"trouble.nvim",
},
config = function()
require("kotlin").setup {
-- Optional: Specify root markers for multi-module projects
root_markers = {
"gradlew",
".git",
"mvnw",
"settings.gradle",
},
-- Optional: Java Runtime to run the kotlin-lsp server itself
-- NOT REQUIRED when using Mason (kotlin-lsp v261+ includes bundled JRE)
-- Priority: 1. jre_path, 2. Bundled JRE (Mason), 3. System java
--
-- Use this if you want to run kotlin-lsp with a specific Java version
-- Must point to JAVA_HOME (directory containing bin/java)
-- Examples:
-- macOS: "/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home"
-- Linux: "/usr/lib/jvm/java-21-openjdk"
-- Windows: "C:\\Program Files\\Java\\jdk-21"
-- Env var: os.getenv("JAVA_HOME") or os.getenv("JDK21")
jre_path = nil, -- Use bundled JRE (recommended)
-- Optional: JDK for symbol resolution (analyzing your Kotlin code)
-- This is the JDK that your project code will be analyzed against
-- Different from jre_path (which runs the server)
-- Required for: Analyzing JDK APIs, standard library symbols, platform types
--
-- Usually should match your project's target JDK version
-- Examples:
-- macOS: "/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home"
-- Linux: "/usr/lib/jvm/java-17-openjdk"
-- Windows: "C:\\Program Files\\Java\\jdk-17"
-- SDKMAN: os.getenv("HOME") .. "/.sdkman/candidates/java/17.0.8-tem"
jdk_for_symbol_resolution = nil, -- Auto-detect from project
-- Optional: Specify additional JVM arguments for the kotlin-lsp server
jvm_args = {
"-Xmx4g", -- Increase max heap (useful for large projects)
},
-- Optional: Configure inlay hints (requires kotlin-lsp v261+)
-- All settings default to true, set to false to disable specific hints
inlay_hints = {
enabled = true, -- Enable inlay hints (auto-enable on LSP attach)
parameters = true, -- Show parameter names
parameters_compiled = true, -- Show compiled parameter names
parameters_excluded = false, -- Show excluded parameter names
types_property = true, -- Show property types
types_variable = true, -- Show local variable types
function_return = true, -- Show function return types
function_parameter = true, -- Show function parameter types
lambda_return = true, -- Show lambda return types
lambda_receivers_parameters = true, -- Show lambda receivers/parameters
value_ranges = true, -- Show value ranges
kotlin_time = true, -- Show kotlin.time warnings
},
}
end,
},
Since different projects may target different JDK versions or require different settings, kotlin.nvim supports per-project configuration via a .kotlin-lsp.lua file in your project root.
Create a .kotlin-lsp.lua file in your project root:
-- Project-specific Kotlin LSP configuration
return {
-- This project targets JDK 21
jdk_for_symbol_resolution = "/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home",
-- Override inlay hints for this project
inlay_hints = {
enabled = false, -- Disable inlay hints for this specific project
},
-- Project-specific JVM args
jvm_args = {
"-Xmx2g", -- Less memory for smaller project
},
}- Global config in your Neovim setup (applies to all projects)
- Project config in
.kotlin-lsp.lua(overrides global for that project) - Project settings are merged with global settings, with project taking precedence
Multi-project workspace with different JDK targets:
~/projects/
βββ legacy-app/ # Uses JDK 11
β βββ .kotlin-lsp.lua # jdk_for_symbol_resolution = "/path/to/jdk-11"
βββ modern-app/ # Uses JDK 21
βββ .kotlin-lsp.lua # jdk_for_symbol_resolution = "/path/to/jdk-21"
Project with specific memory requirements:
-- .kotlin-lsp.lua for large monorepo
return {
jvm_args = { "-Xmx8g" }, -- More memory for large codebase
}Tip
Add .kotlin-lsp.lua to your .gitignore if settings are developer-specific, or commit it if the entire team should use the same configuration.
When using the Mason-installed kotlin-lsp (v261+), no separate JDK installation is required. The language server includes platform-specific builds with a bundled JRE, providing a truly zero-dependency setup experience.
kotlin.nvim provides two separate Java-related configuration options that serve different purposes:
Purpose: Specifies which Java runtime should be used to run the kotlin-lsp server process itself.
Priority:
jre_pathin your config (if specified)- Bundled JRE in Mason installation (kotlin-lsp v261+)
- System
javafrom PATH
When to use:
- You want to run kotlin-lsp with a specific Java version
- You're not using Mason, or using an older kotlin-lsp version without bundled JRE
- You have specific JVM compatibility requirements for the server
Examples:
-- macOS
jre_path = "/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home"
-- Linux
jre_path = "/usr/lib/jvm/java-21-openjdk"
-- Windows
jre_path = "C:\\Program Files\\Java\\jdk-21"
-- Environment variable
jre_path = os.getenv("JAVA_HOME")
-- SDKMAN installation
jre_path = os.getenv("HOME") .. "/.sdkman/candidates/java/21.0.1-tem"Recommendation: Leave as nil to use Mason's bundled JRE (simplest setup).
Purpose: Specifies which JDK should be used to analyze your Kotlin code and resolve symbols/APIs.
When to use:
- Your project targets a specific Java version (e.g., Java 17 or 21)
- You need code completion for JDK-specific APIs
- You want symbol resolution against a particular JDK's standard library
- Different projects use different JDK versions
Examples:
-- Project targeting Java 17
jdk_for_symbol_resolution = "/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home"
-- Project targeting Java 21
jdk_for_symbol_resolution = "/usr/lib/jvm/java-21-openjdk"
-- Per-project configuration (in .kotlin-lsp.lua)
return {
jdk_for_symbol_resolution = "/path/to/project-specific/jdk"
}Recommendation: Set this to match your project's target JDK version for accurate symbol resolution.
| Option | Purpose | Default | Typical Use Case |
|---|---|---|---|
jre_path |
Run the LSP server | Bundled JRE (Mason) | Override server runtime |
jdk_for_symbol_resolution |
Analyze your code | Auto-detect | Match project JDK version |
The latest kotlin-lsp versions offer significantly improved code completion:
- Suggestion ordering on par with IntelliJ IDEA
- ~30% better completion latency
- More relevant and context-aware suggestions
Full support for LSP inlay hints matching the VSCode extension configuration. All hint types are supported with individual toggles.
Minimal configuration (enables all hints with defaults):
require("kotlin").setup {
inlay_hints = {
enabled = true, -- Auto-enable on LSP attach
},
}All settings default to true except parameters_excluded. Only specify settings you want to change:
require("kotlin").setup {
inlay_hints = {
enabled = true, -- Master switch: enable/disable all inlay hints
-- Parameter hints (show parameter names in function calls)
parameters = true, -- foo(name: "value", age: 42)
parameters_compiled = true, -- Show parameter names for compiled code
parameters_excluded = false, -- Show hints for excluded parameters (usually false)
-- Type hints (show inferred types)
types_property = true, -- val name: String = "foo"
types_variable = true, -- val count: Int = 42
function_return = true, -- fun foo(): String { }
function_parameter = true, -- fun foo(name: String) { }
-- Lambda hints
lambda_return = true, -- { x -> x * 2 }: (Int) -> Int
lambda_receivers_parameters = true, -- Show receivers and parameters
-- Other hints
value_ranges = true, -- Show hints for ranges
kotlin_time = true, -- Show kotlin.time warnings
},
}| Setting | Default | Description |
|---|---|---|
enabled |
true |
Master switch to enable/disable all inlay hints |
parameters |
true |
Show parameter names in function calls |
parameters_compiled |
true |
Show parameter names for compiled/external functions |
parameters_excluded |
false |
Show parameter names for excluded parameters |
types_property |
true |
Show type hints for properties |
types_variable |
true |
Show type hints for local variables |
function_return |
true |
Show return type hints for functions |
function_parameter |
true |
Show type hints for function parameters |
lambda_return |
true |
Show return type hints for lambdas |
lambda_receivers_parameters |
true |
Show receiver and parameter hints for lambdas |
value_ranges |
true |
Show hints for value ranges |
kotlin_time |
true |
Show kotlin.time package warnings |
:KotlinInlayHintsToggle- Toggle inlay hints for the current buffer:lua vim.lsp.inlay_hint.enable(true)- Enable inlay hints:lua vim.lsp.inlay_hint.enable(false)- Disable inlay hints
vim.keymap.set('n', '<leader>ih', function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, { desc = 'Toggle inlay hints' })Note: The KotlinHintsToggle command toggles diagnostic hints (HINT severity diagnostics), while KotlinInlayHintsToggle controls LSP inlay hints. These are two different features.
Inlay hints work by implementing a workspace/configuration handler that responds to server requests for the jetbrains.kotlin configuration section. The handler builds a properly nested configuration object matching the VSCode extension format. This is crucial because kotlin-lsp requests configuration dynamically rather than using only the initial settings.
kotlin.nvim provides several commands for working with Kotlin code:
| Command | Description |
|---|---|
:KotlinOrganizeImports |
Organize and optimize imports in the current file |
:KotlinFormat |
Format the current buffer using IntelliJ IDEA formatting rules |
:KotlinSymbols |
Show document symbols/outline for the current buffer (displays in trouble.nvim window) |
:KotlinWorkspaceSymbols |
Search for symbols across the entire workspace (displays in trouble.nvim window) |
:KotlinReferences |
Find all references to the symbol under cursor |
:KotlinRename |
Rename the symbol under cursor across the project |
:KotlinCodeActions |
Show all available code actions from kotlin-lsp |
:KotlinQuickFix |
Show quick fixes for diagnostics on current line |
:KotlinInlayHintsToggle |
Toggle inlay hints on/off for the current buffer |
:KotlinHintsToggle |
Toggle HINT severity diagnostics (if sent by the server) |
:KotlinExportWorkspaceToJson |
Export workspace structure to workspace.json |
:KotlinCleanWorkspace |
Clear cached indices for the current project |
Note
:KotlinSymbols and :KotlinWorkspaceSymbols require trouble.nvim to display results in a clean, interactive window. These commands provide a better alternative to traditional location lists for browsing code structure.
Key Mappings Example:
-- Code actions and quick fixes
vim.keymap.set('n', '<leader>ka', ':KotlinCodeActions<CR>', { desc = 'Kotlin code actions' })
vim.keymap.set('n', '<leader>kq', ':KotlinQuickFix<CR>', { desc = 'Kotlin quick fix' })
-- Organize imports
vim.keymap.set('n', '<leader>ko', ':KotlinOrganizeImports<CR>', { desc = 'Organize Kotlin imports' })
-- Format buffer
vim.keymap.set('n', '<leader>kf', ':KotlinFormat<CR>', { desc = 'Format Kotlin buffer' })
-- Show symbols
vim.keymap.set('n', '<leader>ks', ':KotlinSymbols<CR>', { desc = 'Show document symbols' })
-- Find references
vim.keymap.set('n', '<leader>kr', ':KotlinReferences<CR>', { desc = 'Find references' })
-- Rename symbol
vim.keymap.set('n', '<leader>kn', ':KotlinRename<CR>', { desc = 'Rename symbol' })
-- Toggle inlay hints
vim.keymap.set('n', '<leader>kh', ':KotlinInlayHintsToggle<CR>', { desc = 'Toggle inlay hints' })Indices are now stored in a dedicated folder and properly shared between multiple projects and language server instances, improving performance and reducing disk usage.
The plugin supports two installation methods for kotlin-lsp:
You can easily install kotlin-lsp using Mason with the following command:
:MasonInstall kotlin-lspThis is the recommended approach as Mason handles the installation automatically and includes platform-specific builds with a bundled JRE (zero-dependency installation). No separate JDK installation is required when using the Mason-installed kotlin-lsp.
The plugin will automatically detect and use the bundled JRE from the Mason installation, providing a seamless zero-configuration experience.
If you prefer not to use Mason or need to use a specific version of kotlin-lsp, you can install it manually and set the KOTLIN_LSP_DIR environment variable to point to your installation directory:
export KOTLIN_LSP_DIR=/path/to/your/kotlin-lspThe plugin will automatically detect and use your manual installation when the environment variable is set. Ensure your installation has the following structure:
$KOTLIN_LSP_DIR/
βββ lib/
βββ ... (jar files)
For manual installations, you'll need to provide a JRE either through:
- The
jre_pathconfiguration option - The
JAVA_HOMEenvironment variable - A system-wide
javainstallation
Tip
The plugin automatically prioritizes JRE selection in this order:
- User-specified
jre_pathin configuration - Bundled JRE from Mason kotlin-lsp installation (zero-dependency)
JAVA_HOMEenvironment variable- System-wide
javainstallation
Caution
If you use other tools like nvim-lspconfig or mason-lspconfig, make sure to explicitly exclude the kotlin_lsp configuration there to avoid conflicts.