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
EOF
Here’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 pkl
to manually install the Pkl parser. -
If syntax highlighting doesn’t work until you
:edit
the pkl file to reload it, ensure that thepkl-neovim
plugin is configured to run after thenvim-treesitter
plugin.
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.