Skip to content

AlexandrosAlexiou/kotlin.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

58 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


🧩 Extensions

  • Decompile and open class file contents using kotlin-lsp decompile command
  • Export workspace to JSON using kotlin-lsp exportWorkspace command
  • Organize imports with KotlinOrganizeImports command
  • Format code with KotlinFormat command (uses IntelliJ IDEA formatting)
  • Toggle diagnostic hints using the KotlinHintsToggle command
  • 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 KotlinCleanWorkspace command to clear cached indices for the current project
  • Per-project LSP configuration via .kotlin-lsp.lua file
  • Per-project LSP disabling via marker file
    • Create a .disable-kotlin-lsp file in the project root to prevent the Kotlin LSP from being registered

Note

Version Requirements:

  • Workspace isolation with the --system-path parameter 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.

πŸ“¦ Installation

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 :KotlinSymbols and :KotlinWorkspaceSymbols commands 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,
},

πŸ”§ Per-Project Configuration

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.

Example: .kotlin-lsp.lua

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
    },
}

How It Works

  1. Global config in your Neovim setup (applies to all projects)
  2. Project config in .kotlin-lsp.lua (overrides global for that project)
  3. Project settings are merged with global settings, with project taking precedence

Common Use Cases

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.

✨ Features

Zero-Dependency Installation

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.

Understanding JRE and JDK Options

kotlin.nvim provides two separate Java-related configuration options that serve different purposes:

1. jre_path - Java Runtime for the LSP Server

Purpose: Specifies which Java runtime should be used to run the kotlin-lsp server process itself.

Priority:

  1. jre_path in your config (if specified)
  2. Bundled JRE in Mason installation (kotlin-lsp v261+)
  3. System java from 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).

2. jdk_for_symbol_resolution - JDK for Code Analysis

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.

Quick Reference

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

Enhanced Code Completion

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

Inlay Hints Support

Full support for LSP inlay hints matching the VSCode extension configuration. All hint types are supported with individual toggles.

Quick Start

Minimal configuration (enables all hints with defaults):

require("kotlin").setup {
    inlay_hints = {
        enabled = true,  -- Auto-enable on LSP attach
    },
}

All Available Settings

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
    },
}

Settings Reference

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

Commands

  • :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

Key Mapping Example

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.

Implementation Note

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.

Available Commands

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' })

Shared Indices

Indices are now stored in a dedicated folder and properly shared between multiple projects and language server instances, improving performance and reducing disk usage.

πŸ“₯ Language Server Installation

The plugin supports two installation methods for kotlin-lsp:

Option 1: Mason Installation (Recommended)

You can easily install kotlin-lsp using Mason with the following command:

:MasonInstall kotlin-lsp

This 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.

Option 2: Manual Installation

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-lsp

The 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_path configuration option
  • The JAVA_HOME environment variable
  • A system-wide java installation

Tip

The plugin automatically prioritizes JRE selection in this order:

  1. User-specified jre_path in configuration
  2. Bundled JRE from Mason kotlin-lsp installation (zero-dependency)
  3. JAVA_HOME environment variable
  4. System-wide java installation

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.

πŸ’ Credits

About

Extensions for JetBrains' kotlin-lsp support in Neovim

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages