Nvim:help pages,generated fromsource using thetree-sitter-vimdoc parser.
" List all runtime dirs and packages with Lua paths.:echo nvim_get_runtime_file("lua/", v:true)% mkdir -p ~/.local/share/nvim/site/pack/foo% cd ~/.local/share/nvim/site/pack/foo% unzip /tmp/foopack.zipThe directory name "foo" is arbitrary, you can pick anything you like.
pack/foo/README.txtpack/foo/start/foobar/plugin/foo.vimpack/foo/start/foobar/syntax/some.vimpack/foo/opt/foodebug/plugin/debugger.vimOn startup after processing yourconfig, Nvim scans all directories in'packpath' for plugins in "pack/*/start/*", then loads the plugins.
% mkdir -p ~/.local/share/nvim/site/pack/foo/start/foobar% cd ~/.local/share/nvim/site/pack/foo/start/foobar% unzip /tmp/someplugin.zipYou would now have these files:
pack/foo/start/foobar/plugin/foo.vimpack/foo/start/foobar/syntax/some.vimFrom here it works like above.
:packadd command::packadd foodebugThis searches for "pack/*/opt/foodebug" in'packpath' and will find~/.local/share/nvim/site/pack/foo/opt/foodebug/plugin/debugger.vim and sourceit.
:packadd! foodebugThe extra "!" is so that the plugin isn't loaded if Nvim was started with--noplugin.
:colorscheme, are found below"pack/*/start" and "pack/*/opt", you could put them anywhere. We recommendyou put them below "pack/*/opt", for example"~/.config/nvim/pack/mycolors/opt/dark/colors/very_dark.vim".:packadd. E.g. depending on the compilerversion:if foo_compiler_version > 34 packadd foo_newelse packadd foo_oldendifThe "after" directory is most likely not useful in a package. It's notdisallowed though.
:packadd.start/foobar/plugin/foo.vim " always loaded, defines commandsstart/foobar/plugin/bar.vim " always loaded, defines commandsstart/foobar/autoload/foo.vim " loaded when foo command usedstart/foobar/doc/foo.txt " help for foo.vimstart/foobar/doc/tags " help tagsopt/fooextra/plugin/extra.vim " optional plugin, defines commandsopt/fooextra/autoload/extra.vim " loaded when extra command usedopt/fooextra/doc/extra.txt " help for extra.vimopt/fooextra/doc/tags " help tags
mkdir ~/.local/share/nvim/site/packcd ~/.local/share/nvim/site/packgit clone https://github.com/you/foobar.git myfoobarHere "myfoobar" is a name that the user can choose, the only condition is thatit differs from other packages.
:packadd! fooextraYou could add this packadd command in one of your plugins, to be executed whenthe optional plugin is needed.
:helptags command to generate the doc/tags file. Including thisgenerated file in the package means that the user can drop the package in thepack directory and the help command works right away. Don't forget to re-runthe command after changing the plugin help::helptags path/start/foobar/doc:helptags path/opt/fooextra/doc
call foolib#getit()pack/foo/start/two/plugin/two.vim
call foolib#getit()pack/foo/start/lib/autoload/foolib.vim
func foolib#getit()This works, because start packages will be searched for autoload files, whensourcing the plugins.
$XDG_DATA_HOME/nvim/site/pack/core/opt.$XDG_DATA_HOME/nvim/site needs tobe part of'packpath'. It usually is, but might not be in cases like--cleanor setting$XDG_DATA_HOME during startup. Plugin's subdirectory name matchesplugin's name in specification. It is assumed that all plugins in thedirectory are managed exclusively byvim.pack.git executable. Targetplugins should be Git repositories with versions as named tags followingsemver conventionv<major>.<minor>.<patch>.$XDG_CONFIG_HOME/nvim/nvim-pack-lock.json. It is a JSON file thatis used to persistently track data about plugins. For a more robust configtreat lockfile like its part: put under version control, etc. In this case allplugins from the lockfile will be installed at once and at lockfile's revision(instead of inferring fromversion). Should not be edited by hand. Corrupteddata for installed plugins is repaired (including after deleting whole file),butversion fields will be missing for not yet added plugins.vim.pack.add({ -- Install "plugin1" and use default branch (usually `main` or `master`) 'https://github.com/user/plugin1', -- Same as above, but using a table (allows setting other options) { src = 'https://github.com/user/plugin1' }, -- Specify plugin's name (here the plugin will be called "plugin2" -- instead of "generic-name") { src = 'https://github.com/user/generic-name', name = 'plugin2' }, -- Specify version to follow during install and update { src = 'https://github.com/user/plugin3', -- Version constraint, see |vim.version.range()| version = vim.version.range('1.0'), }, { src = 'https://github.com/user/plugin4', -- Git branch, tag, or commit hash version = 'main', },})-- Plugin's code can be used directly after `add()`plugin1 = require('plugin1')add() call. Their revision is taken fromvim.pack-lockfile (if present) or inferred from theversion.version. Let's say, plugin named 'plugin1' has changed tovim.version.range('*').version invim.pack-lockfile is updated.vim.pack.update({ 'plugin1' }).src.version set to current revision. Get it fromvim.pack-lockfile (plugin's fieldrev; looks likeabc12345).version set to whichever version you want it to be updated.rev field.version and:restart).vim.pack.update({ 'plugin-name' }, { force = true }) to make plugin state on disk follow target revision.:restart.active - whether plugin was added viavim.pack.add() to current session.kind - one of "install" (install on disk; before loading), "update" (update already installed plugin; might be not loaded), "delete" (delete from disk).spec - plugin's specification with defaults made explicit.path - full path to plugin's directory.local hooks = function(ev) -- Use available |event-data| local name, kind = ev.data.spec.name, ev.data.kind -- Run build script after plugin's code has changed if name == 'plug-1' and (kind == 'install' or kind == 'update') then vim.system({ 'make' }, { cwd = ev.data.path }) end -- If action relies on code from the plugin (like user command or -- Lua code), make sure to explicitly load it first if name == 'plug-2' and kind == 'update' then if not ev.data.active then vim.cmd.packadd('plug-2') end vim.cmd('PlugTwoUpdate') require('plug2').after_update() endend-- If hooks need to run on install, run this before `vim.pack.add()`vim.api.nvim_create_autocmd('PackChanged', { callback = hooks }){src} (string) URI from which to install and pull updates. Any format supported bygit clone is allowed.{name}? (string) Name of plugin. Will be used as directory name. Default:src repository name.{version}? (string|vim.VersionRange) Version to use for install and updates. Can be:nil (no value, default) to use repository's default branch (usuallymain ormaster).{data}? (any) Arbitrary data associated with a plugin.{specs},{opts})vim.pack.add()src is the same as input. If not - delete immediately to clean install from the new source. Otherwise do nothing.src intoname subdirectory (via partial bloblessgit clone) and update revision to matchversion (viagit checkout). Plugin will not be on disk if any step resulted in an error.load function) making it reachable by Nvim.version can be not the one actually present on disk. Executevim.pack.update() to synchronize.{specs} ((string|vim.pack.Spec)[]) List of plugin specifications. String item is treated assrc.{opts} (table?) A table with the following fields:{load}? (boolean|fun(plug_data: {spec: vim.pack.Spec, path: string})) Loadplugin/ files andftdetect/ scripts. Iffalse, works like:packadd!. If function, called with plugin data and is fully responsible for loading plugin. Defaultfalse duringinit.lua sourcing andtrue afterwards.{confirm}? (boolean) Whether to ask user to confirm initial install. Defaulttrue.{names} (string[]) List of plugin names to remove from disk. Must be managed byvim.pack, not necessarily already added to current session.{opts} (table?) A table with the following fields:{info} (boolean) Whether to include extra plugin info. Defaulttrue.table[]) A list of objects with the following fields:{branches}? (string[]) Available Git branches (first is default). Missing ifinfo=false.{path} (string) Plugin's path on disk.{rev} (string) Current Git revision.{tags}? (string[]) Available Git tags. Missing ifinfo=false.{names},{opts})vim.pack.update()force:false, show confirmation buffer. It lists data about all set to update plugins. Pending changes starting with> will be applied while the ones starting with< will be reverted. It has dedicated buffer-local mappings:gO vialsp-defaults orvim.lsp.buf.document_symbol()) - show structure of the buffer.K vialsp-defaults orvim.lsp.buf.hover()) - show more information at cursor. Like details of particular pending change or newer tag.gra vialsp-defaults orvim.lsp.buf.code_action()) - show code actions available for "plugin at cursor". Like "delete", "update", or "skip updating". Execute:write to confirm update, execute:quit to discard the update.true, make updates right away.{names} (string[]?) List of plugin names to update. Must be managed byvim.pack, not necessarily already added to current session. Default: names of all plugins managed byvim.pack.{opts} (table?) A table with the following fields:{force}? (boolean) Whether to skip confirmation and make updates immediately. Defaultfalse.