This repository provides language support for Pkl for neovim.
Supported features:
-
Syntax highlighting (via nvim-treesitter)
-
Code folding (via nvim-treesitter)
-
Go-to definition, code completion, typechecking, quick fixes, and more (via Pkl Language Server)
-
Install the plugin through your favorite plugin manager.
-
Download the latest Pkl Language Server
Alternatively, install with homebrew withbrew install pkl-lsp -
Configure the LSP start command and Pkl CLI path:
vim.g.pkl_neovim = { start_command = { "java", "-jar", "/path/to/pkl-lsp.jar" }, -- or if pkl-lsp is installed with brew: -- start_command = { "pkl-lsp" }, pkl_cli_path = "/path/to/pkl" }
-
Neovim version 0.11 or higher.
-
Java 22 or higher
Here is a sample init.vim file using vim-plug.
To complete the setup, you will need to run :PlugInstall, then restart neovim.
call plug#begin()
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
Plug 'https://github.com/apple/pkl-neovim.git'
call plug#end()
" The below is required for enabling the tree-sitter syntax engine, which is used by pkl-neovim.
lua <<EOF
local hasConfigs, configs = pcall(require, "nvim-treesitter.configs")
if hasConfigs then
configs.setup {
ensure_installed = "pkl",
highlight = {
enable = true, -- false will disable the whole extension
},
indent = {
enable = true
}
}
end
EOFHere’s a sample block to add your Lazy.nvim configuration. To complete the setup, restart neovim after adding this to your setup.
This config is compatible with LazyVim.
{
"apple/pkl-neovim",
lazy = true,
ft = "pkl",
dependencies = {
{
"nvim-treesitter/nvim-treesitter",
build = function(_)
vim.cmd("TSUpdate")
end,
},
"L3MON4D3/LuaSnip",
},
build = function()
require('pkl-neovim').init()
-- Set up syntax highlighting.
vim.cmd("TSInstall pkl")
end,
config = function()
-- Set up snippets.
require("luasnip.loaders.from_snipmate").lazy_load()
-- Configure pkl-lsp
vim.g.pkl_neovim = {
start_command = { "java", "-jar", "/path/to/pkl-lsp.jar" },
-- or if pkl-lsp is installed with brew:
-- start_command = { "pkl-lsp" },
pkl_cli_path = "/path/to/pkl"
}
end,
}Here is a sample init.lua file using packer.nvim.
To complete the setup, you will need to run :PackerSync, then restart neovim.
require('packer').startup(function(use)
-- Packer can manage itself
use 'wbthomason/packer.nvim'
use {'nvim-treesitter/nvim-treesitter', run = ':TSUpdate'} -- Treesitter syntax highlighting.
use {'https://github.com/apple/pkl-neovim', after = "nvim-treesitter", run = ":TSInstall pkl"} -- Pkl syntax highlighting
end)
-- The below is required for enabling the tree-sitter syntax engine, which is used by pkl-neovim.
-- Set up Treesitter languages.
require'nvim-treesitter.configs'.setup {
ensure_installed = "all", -- or "pkl" for just this plugin.
highlight = {
enable = true, -- false will disable the whole extension
},
indent = {
enable = true
}
}Some troubleshooting tips if the installation isn’t working:
-
Ensure you are using neovim 0.11 or higher.
-
Run
:TSInstall pklto manually install the Pkl parser. -
If syntax highlighting doesn’t work until you
:editthe pkl file to reload it, ensure that thepkl-neovimplugin is configured to run after thenvim-treesitterplugin.
To configure pkl-neovim, set variables on vim.g.pkl_neovim.
See :h vim.g.pkl_neovim for detailed documentation on all of the available configuration options.
To analyze project dependencies, the Pkl Language Server needs to sync all the PklProjects within the workspace root.
To do this, run the :Pkl syncProjects command.
Alternatively, run lua function require('pkl-neovim').sync_projects().
When starting Pkl Language Server, pkl-neovim will look for the following files/directories to determine what the workspace root is (in descending order of priority):
-
.pkl-lsp/ -
.git/ -
PklProject
If you are working on a non-git based project, it can be helpful to create a .pkl-lsp to mark where the workspace root is.
This allows the language server to discover multiple Pkl projects, and analyze dependency imports in all of them.
This also allows pkl-neovim to determine that the same instance of the language server can be shared between different buffers.