diff options
| author | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2026-07-31 11:28:11 +0300 |
|---|---|---|
| committer | Evgeni Chasnovski <evgeni.chasnovski@gmail.com> | 2026-07-31 18:04:58 +0300 |
| commit | 4cdd6d76c5ad2714aa5c056c8b16fca408120e61 (patch) | |
| tree | 6462dc4cbdd0325abab655a54431a939382b8ae4 /runtime/lua/vim/pack.lua | |
| parent | 02a25caa1b5211e349c41ac2e0642de905ae7be9 (diff) | |
| download | rneovim-4cdd6d76c5ad2714aa5c056c8b16fca408120e61.tar.gz rneovim-4cdd6d76c5ad2714aa5c056c8b16fca408120e61.tar.bz2 rneovim-4cdd6d76c5ad2714aa5c056c8b16fca408120e61.zip | |
feat(pack): introduce plugin manifest support
Problem: There is no agreed way for plugins to provide extra information
about themselves. Like required Neovim version, install/update/delete
hooks, and dependencies.
Solution: Introduce basic concept of plugin manifest file `pkg.json`
based on https://packspec.org/.
Diffstat (limited to 'runtime/lua/vim/pack.lua')
| -rw-r--r-- | runtime/lua/vim/pack.lua | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/runtime/lua/vim/pack.lua b/runtime/lua/vim/pack.lua index 2b456a6dbb..a69684de75 100644 --- a/runtime/lua/vim/pack.lua +++ b/runtime/lua/vim/pack.lua @@ -232,6 +232,25 @@ ----- To act on install from lockfile, run before very first `vim.pack.add()` ---vim.api.nvim_create_autocmd('PackChanged', { callback = hooks }) ---``` +---[vim.pack-manifest]() +--- +---Plugins can come with a special top level `pkg.json` manifest file with extra +---information. If present, `vim.pack` uses it for improved user experience: +---- Running |:checkhealth| for `vim.pack` will perform extra checks to ensure +--- healthy plugin installation. +--- +---Full specification see at https://packspec.org/. See also |vim.pack.Manifest|. +---A simple example: +---```json +---{ +--- "name": "best-plugin.nvim", +--- "description": "The best plugin for Neovim", +--- "engines": { +--- "nvim": ">=0.13.0", +--- "vim": ">=9.1.0" +--- } +---} +---``` local api = vim.api local uv = vim.uv @@ -516,6 +535,37 @@ end local active_plugins = {} local n_active_plugins = 0 +--- @class vim.pack.ManifestEngines +--- @inlinedoc +--- @field nvim? string Version range for Nvim. +--- @field vim? string Version range for Vim. + +--- @class vim.pack.Manifest +--- @field name? string Plugin name +--- @field description? string Plugin description +--- Supported engine versions. Values should be |vim.version.range()| compatible specs. +--- @field engines? vim.pack.ManifestEngines + +--- @param path string +--- @return vim.pack.Manifest? +local function manifest_read(path) + local manifest_path = vim.fs.joinpath(path, 'pkg.json') + local stat = uv.fs_stat(manifest_path) + if not stat then + return nil + end + + local fd = uv.fs_open(manifest_path, 'r', 438) + if not fd then + return {} + end + + local data = assert(uv.fs_read(fd, stat.size, 0)) + assert(uv.fs_close(fd)) + local ok, res = pcall(vim.json.decode, data) + return (ok and type(res) == 'table') and res or {} +end + --- @param plugs vim.pack.Plug[] --- @param event_name 'PackChangedPre'|'PackChanged' --- @param kind 'install'|'update'|'delete' @@ -1468,6 +1518,8 @@ end --- @class vim.pack.PlugData --- @field active boolean Whether plugin was added via |vim.pack.add()| to current session. --- @field branches? string[] Available Git branches (first is default). Missing if `info=false`. +--- Data from the |vim.pack-manifest|. Empty in case of reading error. Missing if `info=false`. +--- @field manifest? vim.pack.Manifest --- @field path string Plugin's path on disk. --- @field rev string Current Git revision. Taken from |vim.pack-lockfile| if `info=false`. --- Git revision of a pending update. The same as used during |vim.pack.update()| and which @@ -1494,6 +1546,7 @@ local function add_p_data_info(p_data_list, offline) funs[i] = function() p_data.branches = git_get_branches(path) p_data.tags = git_get_tags(path) + p_data.manifest = manifest_read(path) if not offline then git_fetch(path) |