kubectl (optional) - for fetching CRD schemas from your Kubernetes cluster:TSInstall yaml)Install the plugin with your preferred package manager:
{
"mosheavni/yaml-companion.nvim",
opts = {
-- Add any options here, or leave empty to use the default settings
-- lspconfig = {
-- settings = { ... }
-- },
},
config = function(_, opts)
local cfg = require("yaml-companion").setup(opts)
vim.lsp.config("yamlls", cfg)
vim.lsp.enable("yamlls")
end,
}
yaml-companion comes with the following defaults (pass these to opts):
{
-- Shared cache directory for all cached data (datree catalog, cluster CRD schemas)
cache_dir = nil, -- Override location (default: stdpath("data")/yaml-companion.nvim/)
-- Built in file matchers
builtin_matchers = {
-- Detects Kubernetes files based on content
kubernetes = { enabled = true },
cloud_init = { enabled = true }
},
-- Additional schemas available in the picker
schemas = {
--{
--name = "Kubernetes 1.32.1",
--uri = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.32.1-standalone-strict/all.json",
--},
},
-- Key navigation features
keys = {
enabled = true, -- Enable key navigation features (creates :YamlKeys command)
include_values = false, -- Show values in quickfix entries
max_value_length = 50, -- Truncate long values in display
},
-- Modeline features
modeline = {
auto_add = {
on_attach = false, -- Auto-add modelines when yamlls attaches
on_save = false, -- Auto-add modelines before saving
},
overwrite_existing = false, -- Whether to overwrite existing modelines
validate_urls = false, -- Check if schema URL exists (slower)
notify = true, -- Show notifications when modelines are added
},
-- Datree CRD catalog settings
datree = {
cache_ttl = 3600, -- Cache TTL in seconds (0 = never expire, -1 = disable)
raw_content_base = "https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/",
},
-- Cluster CRD features
cluster_crds = {
enabled = true, -- Enable cluster CRD features
fallback = false, -- Auto-fallback to cluster when Datree doesn't have schema
cache_ttl = 86400, -- Cache expiration in seconds (default: 24h, 0 = never expire)
},
-- Customize which API groups are considered "core" (skipped by CRD detection)
core_api_groups = {
[""] = true,
["apps"] = true,
["batch"] = true,
["networking.k8s.io"] = true,
-- ... add or remove as needed
},
-- Pass any additional options that will be merged in the final LSP config
lspconfig = {
flags = {
debounce_text_changes = 150,
},
settings = {
redhat = { telemetry = { enabled = false } },
yaml = {
validate = true,
format = { enable = true },
hover = true,
schemaStore = {
enable = true,
url = "https://www.schemastore.org/api/json/catalog.json",
},
schemaDownload = { enable = true },
schemas = {},
trace = { server = "debug" },
},
},
},
}
yaml-companion automatically detects and applies JSON schemas to your YAML files. Schemas are resolved from multiple sources in this order:
schemas tableKubernetes: Detects Kubernetes manifests by scanning for kind: and apiVersion: fields. Core resources (Deployments, Services, ConfigMaps, etc.) are matched to the appropriate Kubernetes JSON schema.
Cloud-init: Detects cloud-config files by checking for #cloud-config header comment.
Both matchers can be disabled via config:
builtin_matchers = {
kubernetes = { enabled = false },
cloud_init = { enabled = false },
}
Open a picker to manually select from all available schemas:
require("yaml-companion").open_ui_select()
This uses vim.ui.select so you can use the picker of your choice (e.g., with dressing.nvim).
When a schema is applied (either automatically or manually), yaml-companion sends LSP progress notifications ($/progress). This integrates with progress UI plugins like fidget.nvim, showing a brief "YAML Schema: <schema_name> schema applied" message.
Show the current schema in your statusline:
local function get_schema()
local schema = require("yaml-companion").get_buf_schema(0)
if schema.result[1].name == "none" then
return ""
end
return schema.result[1].name
end
Navigate YAML keys using treesitter. Requires the YAML treesitter parser (:TSInstall yaml).
Get all YAML keys in a quickfix list for easy navigation:
:YamlKeys
Or via Lua:
require("yaml-companion").get_keys_quickfix()
Each entry shows the full dotted key path:
.metadata.name.spec.containers[0].image.spec.replicasGet the YAML key and value at the current cursor position:
local info = require("yaml-companion").get_key_at_cursor()
if info then
print(info.key) -- ".spec.containers[0].name"
print(info.value) -- "my-container"
print(info.human) -- ".spec.containers[0].name = my-container"
print(info.line) -- 15
print(info.col) -- 5
end
Example keymaps:
vim.keymap.set("n", "<leader>yk", function()
local info = require("yaml-companion").get_key_at_cursor()
if info then
vim.fn.setreg("+", info.key)
vim.notify("Copied: " .. info.key)
end
end, { desc = "Copy YAML key path" })
vim.keymap.set("n", "<leader>yv", function()
local info = require("yaml-companion").get_key_at_cursor()
if info and info.value then
vim.fn.setreg("+", info.value)
vim.notify("Copied: " .. info.value)
end
end, { desc = "Copy YAML value" })
Modelines are special YAML comments that tell yaml-language-server which schema to use:
# yaml-language-server: $schema=https://example.com/schema.json
apiVersion: v1
kind: ConfigMap
Modelines persist in the file, ensuring everyone editing it gets the same schema support.
Browse the datreeio/CRDs-catalog and select a schema:
:YamlBrowseDatreeSchemas
Or via Lua:
require("yaml-companion").open_datree_crd_select()
This opens a picker to select a CRD schema, then asks how to apply it:
Direct action (skip the second prompt):
:YamlBrowseDatreeSchemas modeline " Add as modeline
:YamlBrowseDatreeSchemas lsp " Set as LSP schema
Or via Lua:
require("yaml-companion").open_datree_crd_select("modeline")
require("yaml-companion").open_datree_crd_select("lsp")
Detect Custom Resource Definitions in the current buffer and add schema modelines automatically:
:YamlAddCRDModelines
Or via Lua:
-- Add modelines for all detected CRDs
require("yaml-companion").add_crd_modelines()
-- Preview what would be added (dry run)
require("yaml-companion").add_crd_modelines(0, { dry_run = true })
-- Overwrite existing modelines
require("yaml-companion").add_crd_modelines(0, { overwrite = true })
This parses the buffer for kind: and apiVersion: fields, identifies non-core Kubernetes resources,
and adds modelines pointing to the appropriate schema in the Datree CRD catalog.
Core Kubernetes resources (Deployments, Services, ConfigMaps, etc.) are skipped since they're handled by the builtin kubernetes matcher.
Enable automatic modeline addition:
modeline = {
auto_add = {
on_attach = true, -- Auto-add modelines when yamlls attaches
on_save = true, -- Auto-add modelines before saving
},
}
For CRDs that are not available in the Datree catalog (e.g., custom/internal CRDs specific to your organization),
yaml-companion can fetch schemas directly from your Kubernetes cluster using kubectl.
Enable cluster CRD features in your config:
cluster_crds = {
enabled = true,
}
Requirements:
kubectl must be installed and in your PATHFetch the schema for CRDs detected in your current buffer:
:YamlFetchClusterCRD
Or via Lua:
require("yaml-companion").fetch_cluster_crd(0)
This command:
apiVersion and kind)kubectl get crdBrowse and select from all CRDs installed in your cluster:
:YamlBrowseClusterCRDs
Or via Lua:
require("yaml-companion").open_cluster_crd_select()
This opens a picker showing all CRDs in your cluster. After selecting, you choose how to apply it:
Direct action (skip the second prompt):
:YamlBrowseClusterCRDs modeline " Add as modeline
:YamlBrowseClusterCRDs lsp " Set as LSP schema
Or via Lua:
require("yaml-companion").open_cluster_crd_select("modeline")
require("yaml-companion").open_cluster_crd_select("lsp")
Enable automatic fallback to cluster CRD fetching when Datree doesn't have a schema:
cluster_crds = {
enabled = true,
fallback = true, -- Auto-fallback to cluster when Datree doesn't have schema
},
modeline = {
auto_add = {
on_attach = true, -- or on_save = true
},
}
With this setup:
[!NOTE] When
fallback = true,modeline.validate_urlsis automatically set totrue(to check if Datree URLs exist before using them). If you explicitly setvalidate_urls = falsewhilefallback = true, the plugin will throw an error at startup.
yaml-companion caches data to improve performance and enable offline usage.
By default, caches are stored in:
~/.local/share/nvim/yaml-companion.nvim/
├── crd-cache/ # Cluster CRD schemas (per kubectl context)
│ └── <context>/
│ └── <crd-name>.json
└── datree-catalog.json # Datree CRD catalog index
Override the location:
cache_dir = "/path/to/custom/cache",
Configure how long cached data remains valid:
datree = {
cache_ttl = 3600, -- Datree catalog TTL in seconds (default: 1 hour)
-- 0 = never expire, -1 = disable caching
},
cluster_crds = {
cache_ttl = 86400, -- Cluster CRD schemas TTL (default: 24 hours)
-- 0 = never expire
},
To manually clear the cache, delete the cache directory:
rm -rf ~/.local/share/nvim/yaml-companion.nvim/
Or clear only cluster CRD schemas:
rm -rf ~/.local/share/nvim/yaml-companion.nvim/crd-cache/
| Command | Description |
|---|---|
:YamlKeys |
Open quickfix with all YAML keys in the buffer |
:YamlBrowseDatreeSchemas [action] |
Browse Datree CRD catalog. Optional: modeline or lsp to skip action prompt |
:YamlAddCRDModelines |
Detect CRDs in buffer and add schema modelines |
:YamlFetchClusterCRD |
Fetch CRD schema from Kubernetes cluster for current buffer |
:YamlBrowseClusterCRDs [action] |
Browse all CRDs in your cluster. Optional: modeline or lsp to skip action prompt |
All public functions are available via require("yaml-companion"):
| Function | Description |
|---|---|
setup(opts) |
Initialize the plugin with configuration options |
get_buf_schema(bufnr) |
Get the current schema for a buffer |
set_buf_schema(bufnr, schema) |
Set the schema for a buffer |
open_ui_select() |
Open schema picker (all available schemas) |
open_datree_crd_select(action?) |
Browse Datree catalog. If action is nil, prompts user; if "modeline" or "lsp", applies directly |
open_cluster_crd_select(action?) |
Browse CRDs from cluster. If action is nil, prompts user; if "modeline" or "lsp", applies directly |
fetch_cluster_crd(bufnr) |
Fetch CRD schema from cluster for buffer |
add_crd_modelines(bufnr, opts) |
Auto-detect CRDs and add modelines |
get_modeline(bufnr) |
Get modeline info from a buffer |
get_keys_quickfix(bufnr, opts) |
Get all YAML keys in quickfix format |
get_key_at_cursor() |
Get key info at current cursor position |
load_matcher(name) |
Load a custom matcher |
Run :checkhealth yaml-companion to verify your setup:
This repository was originally forked from someone-stole-my-name/yaml-companion.nvim. It has since been unforked and is now maintained independently. The original commit history has been preserved.