Install the plugin with your preferred package manager:
{
"mosheavni/yaml-companion.nvim",
}
yaml-companion comes with the following defaults:
{
-- 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",
--},
},
-- 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" },
},
},
},
}
local cfg = require("yaml-companion").setup({
-- Add any options here, or leave empty to use the default settings
-- lspconfig = {
-- settings = { ... }
-- },
})
vim.lsp.config("yamlls", cfg)
vim.lsp.enable("yamlls")
No mappings included, you need to map it yourself or call it manually:
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).
You can show the current schema in your statusline using a function like:
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:
-- Open quickfix with all keys
require("yaml-companion").get_keys_quickfix()
-- Or use the command
:YamlKeys
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
This API is useful for building custom integrations. For example, to copy the current key path to clipboard:
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" })
-- Or to copy the value:
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" })
require("yaml-companion").setup({
keys = {
enabled = true, -- Enable key navigation features (creates :YamlKeys command)
include_values = false, -- Show values in quickfix entries (default: false)
max_value_length = 50, -- Truncate long values in display (when include_values = true)
},
})
Note: Treesitter with YAML parser is required. Check with :checkhealth yaml-companion.
yaml-companion provides tools for working with YAML modelines (# yaml-language-server: $schema=...)
to provide schema support for Custom Resource Definitions (CRDs).
Browse the datreeio/CRDs-catalog and add a modeline to the current buffer:
require("yaml-companion").open_datree_crd_select()
This fetches the catalog from GitHub (cached for 1 hour) and presents a picker to select a CRD schema. When selected, a modeline is added at the top of your file:
# yaml-language-server: $schema=https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/argoproj.io/application_v1alpha1.json
apiVersion: argoproj.io/v1alpha1
kind: Application
Detect Custom Resource Definitions in the current buffer and add schema modelines automatically:
-- 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.
require("yaml-companion").setup({
-- 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 catalog for 1 hour (0 = no cache)
raw_content_base = "https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/",
},
-- Customize which API groups are considered "core" (skipped by CRD detection)
-- These are handled by the builtin kubernetes matcher
core_api_groups = {
[""] = true,
["apps"] = true,
["batch"] = true,
["networking.k8s.io"] = true,
-- ... add or remove as needed
},
})