Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shibboleth.nvim

tests

shib·bo·leth — a small utterance that reveals what one is.

A Neovim plugin that inserts and updates schema-pointer directives in configuration files, so any editor or LSP that reads them can validate the file against the right schema. Resolves candidate schemas by matching the buffer's path against a curated set of pairings.

This is meant to complement, not replace, your existing LSP / language-server setup. Instead of relying on per-machine editor config to bind a file to a schema, it writes a directive that rides in version-control within the file itself, so every collaborator's editor picks up the same schema without having a similar setup as yours.

Supports JSON, YAML, and TOML out of the box.

Bonus feature: Write a Vim filetype modeline so a file's intended filetype rides in version control — useful for extension-less scripts and ambiguous files.

What it writes

Filetype Directive Example
JSON top-level $schema property "$schema": "https://json.schemastore.org/package.json"
YAML # yaml-language-server: $schema=... modeline # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
YAML (alt) # $schema: ... (IntelliJ-compatible) # $schema: https://json.schemastore.org/github-workflow.json
TOML Taplo #:schema directive #:schema https://json.schemastore.org/pyproject.json
any Vim filetype modeline # vim: set ft=ruby:

Installation

With lazy.nvim:

{
  'bezhermoso/shibboleth.nvim',
  event = 'VeryLazy',
  opts = {},
}

Requirements:

  • Neovim 0.10+
  • Tree-sitter json parser (for the JSON handler)
  • curl (only if you use the SchemaStore loader)

Run :checkhealth shibboleth to verify.

:Shibboleth Command & Subcommands

" Schema directive (the primary operation)
:Shibboleth                      " open schema picker for current buffer
:Shibboleth <url>                " set schema URL directly (no picker)
:Shibboleth remove               " remove existing directive

" Filetype modeline (the bonus feature)
:Shibboleth modeline             " write `# vim: set ft=<bo.filetype>:` modeline
:Shibboleth modeline <ft>        " write modeline with explicit filetype
:Shibboleth modeline remove      " remove modeline

" SchemaStore catalog
:Shibboleth schemastore          " load catalog (uses cache after first fetch)
:Shibboleth schemastore refresh  " force refetch from network

:Shibboleth resolves candidates by matching the buffer's path against a curated set of file globs (e.g. package.json → npm schema, **/.github/workflows/*.yml → GitHub Actions schema, **/.claude/settings.json → Claude Code settings).

:Shibboleth modeline uses the buffer's existing filetype (vim.bo.filetype). If neither the buffer's filetype nor an explicit <ft> argument is available, it prompts for one via vim.ui.input.

Note

For extension-less scripts where you want the filetype detected from a shebang, install something like shebang.nvim or rely on Neovim's built-in filetype detection (vim.filetype). Then run :Shibboleth modeline to persist that filetype hint into the file.

Configuration

require('shibboleth').setup({
  yaml = {
    style = 'modeline', -- 'modeline' (default) or 'intellij'
  },
  fallback_commentstring = '# %s',

  -- Add custom schemas
  schemas = {
    ['my-thing'] = {
      name = 'My Thing config',
      url = 'https://example.com/my-thing.schema.json',
      ft = { 'yaml' },
    },
  },

  -- Add custom glob patterns. `schema` references a key from the schemas table above.
  patterns = {
    { pattern = '*.mything.{yml,yaml}', schema = 'my-thing' },
  },
})

Optional: load SchemaStore catalog

For the long tail of schemas (1,200+ entries from json.schemastore.org), opt in via either the command or the Lua API.

:Shibboleth schemastore          " load (uses local cache after first fetch)
:Shibboleth schemastore refresh  " force refresh from the network
require('shibboleth.registry.schemastore').load()
require('shibboleth.registry.schemastore').load({ force = true })

This fetches the catalog of schemas and merges them into your registry. The catalog is cached at stdpath('cache')/shibboleth/catalog.json; subsequent loads use the cache unless refresh (or force = true) is passed.

Development

make test          # run the plenary test suite
make test-watch    # re-run on every save (requires entr)
make lint          # luacheck if installed

Why not yaml-companion.nvim / SchemaStore.nvim?

These tools are complementary, not competing.

  • yaml-companion.nvim picks a YAML schema and tells the LSP about it via workspace/didChangeConfiguration. The choice lives in your Neovim session and is YAML-only.
  • SchemaStore.nvim supplies catalog data to your LSP server config.
  • shibboleth.nvim writes a persistent directive into the file itself, across JSON / YAML / TOML, so the schema choice is portable, version- controlled, and visible to any editor with the right LSP — not just your Neovim.

You can use all three.

About

Teach JSON, YAML, and TOML files to introduce themselves to any LSP.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages