This is an implementation of the Language Server Protocol for the Kotlin programming language, leveraging the Kotlin Analysis API to provide real time diagnostics, syntax and semantic analysis of Kotlin source files and libraries.
Right now, this language server is at its infancy and thus not ready to use for production environments (yet). As of now, this language server is being prepared to analyse its own codebase, with upcoming support for other projects. Here are the most important steps to make in order to improve its usability:
-
Integration with build systems: right now we have 2 integrations available:
- Gradle: basic support for single module projects is supported
- File-based: for other build systems, you can write a
.kotlinlsp-modules.json
file at the root of your project with the modules and dependencies it contains. You have an example at.kotlinlsp-modules.template.json
with the dependencies for this project
-
Indexing solution: to provide features like autocomplete and search references, as well as caching to improve analysis performance, we need to create an index where we store all the references used in the project. For this we are using multiple key value stores using RocksDB on disk and perform a background indexing of the whole project, and incrementally update it as the user modifies the source files. One of the goals of this LS is to provide a fast startup time, so diagnostics are reported as quick as possible.
- ✅ Real time diagnostics: working for this codebase
- ✅ Hover: fully working
- 🚧 Go to definition: working except for kotlin binary dependencies (considering using the background index for this if we cannot make it work), it would also be nice to use a decompiler to jump into .class files (the analysis api provides
KotlinClassFileDecompiler
for kotlin .class files, fernflower may be used for java .class files) - 🚧 Build system integration: there is basic support for single module gradle projects available, but needs work to support multimodule projects and Android projects.
To build the language server, just run the ./build.sh
script at the root directory, which compiles the project using gradle, packs it as a distribution zip and decompresses it in the ./lsp-dist
folder. Once built, you need to integrate it in a code editor to test its functionality. For example, in neovim the following config can be used:
local root_dir = vim.fs.root(0, {"settings.gradle.kts", "settings.gradle"})
if not root_dir then
root_dir = vim.fs.root(0, {"build.gradle.kts", "build.gradle"})
end
local lsp_folder = "... path to lsp-dist folder ..."
vim.lsp.config['kotlinlsp'] = {
cmd = { '' .. lsp_folder .. '/app-0.1/bin/app' },
filetypes = { 'kotlin' },
root_dir = root_dir
}
vim.lsp.enable('kotlinlsp')
We need to do an extra step to configure the modules which will be used by the LSP. As of today the language server does not have integrations with build systems like gradle, so for the time being the modules used are read from a .kotlinlsp-modules.json
file. To set it up, run these commands:
cp .kotlinlsp-modules.template.json .kotlinlsp-modules.json
# Changes the template with your home folder so jar dependencies are picked up correctly
sed -i "s|<your-home-folder>|$HOME|g" .kotlinlsp-modules.json
After that, run the code editor in a kotlin file from this project and you should see diagnostics being reported. Also a ./log.txt
file will be created logging the calls to the services in the platform interface, to help troubleshoot bugs and track missing functionality. In the Log.kt
file you can configure the verbosity of the logs.
To run the tests, just run the ./gradlew test
command. The tests are made around the LSP interface so we test against real user interactions, providing a good safety net in case of refactoring or updating dependencies.
Contributions are welcome! I try to improve this language server in my spare time but progress will be slow if I do it all by myself, so the more contributors this project has, the faster the development will be. Feel free to contact me if you want to contribute, have any doubts about how to start or if you need some more context about the Analysis API (which I'm not an expert, but I can provide my own research to help the development of the project).
Feel free to create issues and submit pull requests, I'll answer them as soon as I can.
To help in the development of this project, these resources are extremely valuable:
- Kotlin Analysis API: especially the standalone platform, which is a static read only platform implementation we can use as a baseline
- IntelliJ IDEA Kotlin plugin: the kotlin plugin implements the Analysis API as well implementing the platform interface, so we have it as a base
If you want to economically support this project, I accept donations via