*vimpack.txt* Install Neovim plugins from archives on an artifact registry ============================================================================== CONTENTS *vimpack-contents* 1. Introduction ............................. |vimpack-introduction| 2. Setup .................................... |vimpack-setup| 3. Plugin spec .............................. |vimpack-spec| 4. Registries ............................... |vimpack-registries| 5. Auth ..................................... |vimpack-auth| 6. Commands ................................. |vimpack-commands| 7. Layout ................................... |vimpack-layout| 8. Lua API .................................. |vimpack-api| ============================================================================== 1. INTRODUCTION *vimpack-introduction* vimpack installs Neovim plugins from tarballs or zips served by an artifact registry, at an explicit version, rather than by cloning git repositories. Downloads are checksum-verified and swapped into place atomically, so a failed install never leaves a half-written plugin behind. Requirements: Neovim 0.10+, `curl`, and `tar` (plus `unzip` for .zip archives). ============================================================================== 2. SETUP *vimpack-setup* >lua require('vimpack').setup({ registry = { kind = 'artifactapi', base_url = 'https://artifactapi.k8s.syd1.au.unkin.net', repo = 'nvim-plugins', auth = { env = 'ARTIFACTAPI_TOKEN' }, }, plugins = { { name = 'telescope.nvim', version = '0.1.8' }, { name = 'vim-fugitive', version = '3.7', opt = true }, }, concurrency = 4, timeout = 120000, }) < `setup()` validates the spec and returns the normalised config, or nil plus an error message. Nothing is downloaded until |:VimpackInstall|. Top-level options ~ registry default registry for every plugin (table, optional) plugins list of plugin specs (list, default {}) concurrency maximum simultaneous downloads (number, default 4) timeout per-download timeout in milliseconds (number, default 120000) ============================================================================== 3. PLUGIN SPEC *vimpack-spec* name Plugin name. Required. Also the directory name under pack/vimpack/{start,opt}/ unless dir_name overrides it. version Required unless `url` is given. Passed to the resolver. sha256 Expected digest of the archive. A mismatch aborts the install and reports both the expected and the actual digest. opt When true the plugin lands in opt/ for |:packadd|. url Fully explicit archive URL; registry resolution is skipped. ext Archive extension, default "tar.gz". registry Per-plugin registry, overriding the top-level one. dir_name On-disk directory name. ============================================================================== 4. REGISTRIES *vimpack-registries* A registry maps (name, version) to a download URL. `kind` selects the resolver; the default kind is "template". template ~ Substitutes ${name}, ${version}, ${ext}, ${slug}, ${repo} and ${base_url} into `url_template`. An unrecognised placeholder is reported as an error. `filename_template` optionally names the cached archive. >lua registry = { kind = 'template', url_template = 'https://artifactory.example.com/artifactory/nvim-generic/' .. '${name}/${version}/${name}-${version}.${ext}', } < artifactapi ~ Builds ${base_url}/api/v2/remotes/${repo}/files/${path}. `path_template` defaults to "${name}/${name}-${version}.${ext}". >lua registry = { kind = 'artifactapi', base_url = 'https://artifactapi.k8s.syd1.au.unkin.net', repo = 'nvim-plugins', } < custom ~ A resolver is `(spec, registry) -> resolved | nil, err`, where `resolved` is `{ url, headers, filename, sha256? }`. >lua require('vimpack').register_resolver('mine', function(spec, registry) return { url = registry.base_url .. '/' .. spec.name .. '-' .. spec.version .. '.tar.gz', headers = {} } end) < ============================================================================== 5. AUTH *vimpack-auth* Tokens are never stored in the config. `registry.auth` accepts: env name of an environment variable holding the token token_cmd command (list or shell string) that prints the token header header name, default "Authorization" prefix value prefix, default "Bearer " for Authorization A literal `token` key is rejected at |vimpack-setup| time. >lua auth = { header = 'X-JFrog-Art-Api', prefix = '', token_cmd = { 'pass', 'show', 'artifactory/api-key' } } < ============================================================================== 6. COMMANDS *vimpack-commands* *:VimpackInstall* :VimpackInstall [{name}...] Install plugins that are missing or whose installed version, digest or start/opt placement has drifted from the spec. Up-to-date plugins are skipped. With names, restrict the work to those plugins. *:VimpackUpdate* :VimpackUpdate [{name}...] Re-fetch plugins whether or not the manifest says they are current. *:VimpackClean* :VimpackClean Remove installed plugins and manifest entries that are no longer in the spec. *:VimpackStatus* :VimpackStatus Print wanted versus installed version per plugin, with a state of "ok", "missing", "drift" or "orphan". ============================================================================== 7. LAYOUT *vimpack-layout* stdpath('cache')/vimpack/archives/ downloaded archives stdpath('data')/site/pack/vimpack/.vimpack-stage/ extraction staging area stdpath('data')/vimpack/manifest.json installed name/version/sha256 stdpath('data')/site/pack/vimpack/start/ stdpath('data')/site/pack/vimpack/opt/ An install extracts to the staging area, hoists a single wrapper directory if the archive has one, then renames into place after parking any previous tree aside. If the rename fails the previous tree is restored. Staging sits under the pack root so that rename stays on one filesystem. Every member is listed and validated before extraction: absolute paths, `..` and `..\` escapes, devices, fifos and links pointing out of the destination are all refused. Zip symlink targets are read with `unzip -p` (stdout only, nothing written) because the zip listing does not carry them. Lazy loading is out of scope: `opt = true` only chooses the opt/ bucket. ============================================================================== 8. LUA API *vimpack-api* require('vimpack').setup(opts) configure; returns cfg or nil,err require('vimpack').install(names?) same as |:VimpackInstall| require('vimpack').update(names?) same as |:VimpackUpdate| require('vimpack').clean() same as |:VimpackClean| require('vimpack').status() same as |:VimpackStatus| require('vimpack').status_rows() status as a list of tables require('vimpack').register_resolver(n, fn) add a registry resolver vim:tw=78:ts=8:ft=help:norl: