Syntax highlighting for Helm templates using tree-sitter, plus helm-ls.
Install from the Zed extension store.
You do not need to install helm-ls first. The extension looks for helm_ls, then helm-ls, on PATH. If neither is there, it downloads a pinned helm-ls release and reuses that binary on later Zed starts.
yaml-language-server is still required for full LSP. helm-ls shells out to it for Kubernetes schema validation. Without it you get Helm template intelligence only.
You can also pin a binary:
{
"lsp": {
"helm_ls": {
"binary": {
"path": "/usr/local/bin/helm_ls",
"arguments": ["serve"]
}
}
}
}This matches the official Zed Helm docs. .tpl, .gotmpl, helmfile.yaml, and helmfile.yml are Helm out of the box. Chart templates still share .yaml with ordinary YAML, so map those in settings.json:
{
"file_types": {
"Helm": [
"**/templates/**/*.tpl",
"**/templates/**/*.yaml",
"**/templates/**/*.yml",
"**/templates/**/*.gotmpl",
"**/helmfile.d/**/*.yaml",
"**/helmfile.d/**/*.yml",
"helmfile.yaml",
"helmfile.yml",
"**/values*.yaml",
"**/values*.yml"
]
}
}Leave Chart.yaml as YAML. It is chart metadata, not a template. Path globs such as charts/*/templates/*.yaml are not valid in languages/helm/config.toml path_suffixes; those stay in file_types.
If a .yaml file still opens as YAML, pick Helm in the language selector once, or add the glob above. helm-ls will not start on files that stay tagged as YAML, and yaml-language-server will flag {{ }} as errors.
**/values*.yaml is included because helm-ls understands values files.
helm-ls reads the helm-ls section of workspace configuration. Put that nested object under lsp.helm_ls.settings (lsp.helm and lsp.helm-ls also work). These two shapes are equivalent:
{
"lsp": {
"helm_ls": {
"settings": {
"yamlls": {
"enabled": false
}
}
}
}
}{
"lsp": {
"helm_ls": {
"settings": {
"helm-ls": {
"logLevel": "info",
"yamlls": {
"enabled": true,
"enabledForFilesGlob": "*.{yaml,yml}"
}
}
}
}
}
}yamlls.enabled only controls the yaml-language-server process that helm-ls starts. It does not disable Zed's own YAML language server. If CRDs are still underlined, the buffer is probably still language YAML. Use the file_types globs above.
Full helm-ls options: helm-ls configuration.
The vendored helm grammar keeps {}, the rest of that line, and the trailing newline as one text token so typing at EOL after emptyDir: {} does not sit on the next node's start. YAML is injected per (text) node, not combined (zed#57341).
cargo test
./scripts/check-queries.sh
./scripts/check-grammar.sh
./scripts/check-grammar-pin.sh
./scripts/check-zed-queries.shCI also packages with the zed-extension CLI and runs ts_query_ls format --check languages.
Highlighting uses tree-sitter-go-template, including the empty-mapping lexer fix from tree-sitter-go-template#53.
- Bump the version in
Cargo.tomlandextension.toml. - After release, update the entry in zed-industries/extensions.