Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

lewis6991/pckr.nvim

Repository files navigation

pckr.nvim

Spiritual successor of https://github.com/wbthomason/packer.nvim

Main differences to packer.nvim:

  • Heavily refactored
  • Lockfile support
  • No compilation

Table of Contents

  1. Features
  2. Requirements
  3. Quickstart
  4. Example
  5. Commands
  6. Usage
    1. The setup and add functions
    2. Custom Initialization
    3. Specifying Plugins
    4. Performing plugin management operations
  7. Debugging

Features

  • Declarative plugin specification
  • Support for dependencies
  • Extensible
  • Post-install/update hooks
  • Support for git tags, branches, revisions
  • Support for local plugins
  • Lockfile support

Requirements

  • You need to be running Neovim v0.9 or newer
  • If you are on Windows 10, you need developer mode enabled in order to use local plugins (creating symbolic links requires admin privileges on Windows - credit to @TimUntersberger for this note)

Quickstart

If you want to automatically install and set up pckr.nvim on any machine you clone your configuration to, add the following snippet somewhere in your config before your first usage of pckr:

local function bootstrap_pckr()
 local pckr_path = vim.fn.stdpath("data") .. "/pckr/pckr.nvim"
 if not (vim.uv or vim.loop).fs_stat(pckr_path) then
 vim.fn.system({
 'git',
 'clone',
 "--filter=blob:none",
 'https://github.com/lewis6991/pckr.nvim',
 pckr_path
 })
 end
 vim.opt.rtp:prepend(pckr_path)
end
bootstrap_pckr()
require('pckr').add{
 -- My plugins here
 -- 'foo1/bar1.nvim';
 -- 'foo2/bar2.nvim';
}

Example

-- This file can be loaded by calling `lua require('plugins')` from your init.vim
local cmd = require('pckr.loader.cmd')
local keys = require('pckr.loader.keys')
require('pckr').add{
 -- Simple plugins can be specified as strings
 '9mm/vim-closer';
 -- Lazy loading:
 -- Load on a specific command
 {'tpope/vim-dispatch',
 cond = {
 cmd('Dispatch'),
 }
 };
 -- Load on specific keymap
 {'tpope/vim-commentary', cond = keys('n', 'gc') },
 -- Load on specific commands
 -- Also run code after load (see the "config" key)
 { 'w0rp/ale',
 cond = cmd('ALEEnable'),
 config = function()
 vim.cmd[[ALEEnable]]
 end
 };
 -- Local plugins can be included
 '~/projects/personal/hover.nvim';
 -- Plugins can have post-install/update hooks
 {'iamcco/markdown-preview.nvim', run = 'cd app && yarn install', cond = cmd('MarkdownPreview')};
 -- Post-install/update hook with neovim command
 { 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate' };
 -- Post-install/update hook with call of vimscript function with argument
 { 'glacambre/firenvim', run = function()
 vim.fn['firenvim#install'](0)
 end };
 -- Use specific branch, dependency and run lua file after load
 { 'glepnir/galaxyline.nvim',
 branch = 'main',
 requires = {'kyazdani42/nvim-web-devicons'},
 config = function()
 require'statusline'
 end
 };
 -- Run config *before* the plugin is loaded
 {'whatyouhide/vim-lengthmatters', config_pre = function()
 vim.g.lengthmatters_highlight_one_column = 1
 vim.g.lengthmatters_excluded = {'pckr'}
 end},
}

Commands

pckr provides the following commands.

" Remove any disabled or unused plugins
:Pckr clean
" Install missing plugins
:Pckr install [plugin]+
" Update installed plugins
:Pckr update [plugin]+
" Upgrade pckr.nvim
:Pckr upgrade
" Clean, install, update and upgrade
:Pckr sync [plugin]+
" View status of plugins
:Pckr status
" Create a lockfile of plugins with their current commits
:Pckr lock
" Restore plugins using saved lockfile
:Pckr restore

Usage

The following is a more in-depth explanation of pckr's features and use.

The setup and add functions

pckr providespckr.add(spec), which is used in the above examples where spec is a table specifying a single or multiple plugins.

Custom Initialization

pckr.setup() can be used to provide custom configuration (note that this is optional). The default configuration values (and structure of the configuration table) are:

require('pckr').setup{
 pack_dir = util.join_paths(vim.fn.stdpath('data'), 'site'),
 max_jobs = nil, -- Limit the number of simultaneous jobs. nil means no limit
 autoremove = false, -- Remove unused plugins
 autoinstall = true, -- Auto install plugins
 git = {
 cmd = 'git', -- The base command for git operations
 clone_timeout = 60, -- Timeout, in seconds, for git clones
 default_url_format = 'https://github.com/%s' -- Lua format string used for "aaa/bbb" style plugins
 },
 log = { level = 'warn' }, -- The default print log level. One of: "trace", "debug", "info", "warn", "error", "fatal".
 opt_dir = ...,
 start_dir = ...,
 lockfile = {
 path = util.join_paths(vim.fn.stdpath('config', 'pckr', 'lockfile.lua'))
 }
}

Specifying plugins

pckr is based around declarative specification of plugins.

  1. Absolute paths to a local plugin
  2. Full URLs (treated as plugins managed with git)
  3. username/repo paths (treated as Github git plugins)

Plugin specs can take two forms:

  1. A list of plugin specifications (strings or tables)
  2. A table specifying a single plugin. It must have a plugin location string as its first element, and may additionally have a number of optional keyword elements, shown below:
{
 'myusername/example', -- The plugin location string
 -- The following keys are all optional
 -- Specifies a git branch to use
 branch: string?,
 -- Specifies a git tag to use. Supports '*' for "latest tag"
 tag: string?,
 -- Specifies a git commit to use
 commit: string?,
 -- Skip updating this plugin in updates/syncs. Still cleans.
 lock: boolean?,
 -- Post-update/install hook. See "update/install hooks".
 run: string|function,
 -- Specifies plugin dependencies. See "dependencies".
 requires: string|string[],
 -- Specifies code to run after this plugin is loaded. If string then require it.
 -- E.g:
 -- config = function() require('mod') end
 -- is equivalent to:
 -- config = 'mod'
 config: string|function,
 -- Specifies code to run before this plugin is loaded. If string then require it.
 config_pre: string|function,
 cond: function|function[], -- Specifies custom loader
}

Update/install hooks

You may specify operations to be run after successful installs/updates of a plugin with the run key. This key may either be a Lua function, which will be called with the plugin table for this plugin (containing the information passed to the spec as well as output from the installation/update commands, the installation path of the plugin, etc.), a string, or a table of functions and strings.

If an element of run is a string, then either:

  1. If the first character of run is ":", it is treated as a Neovim command and executed.
  2. Otherwise, run is treated as a shell command and run in the installation directory of the plugin via $SHELL -c '<run>'.

Dependencies

Plugins may specify dependencies via the requires key. This key can be a string or a list (table).

If requires is a string, it is treated as specifying a single plugin. If a plugin with the name given in requires is already known in the managed set, nothing happens. Otherwise, the string is treated as a plugin location string and the corresponding plugin is added to the managed set.

If requires is a list, it is treated as a list of plugin specifications following the format given above.

Plugins specified in requires are removed when no active plugins require them.

🚧 TODO: explain that plugins can only be specified as a table once.

Custom loader

A custom loader for a plugin may be specified via cond. This is a function which has a function as its first argument. When this function argument is called, the plugin is loaded.

For example, the following plugin is lazy-loaded on the key mapping ga:

pckr.add{
 {"my/plugin", cond = function(load_plugin)
 vim.keymap.set('n', 'ga', function()
 vim.keymap.del('n', 'ga')
 load_plugin()
 vim.api.nvim_input('ga')
 end)
 end}
}
 -- equivalent to --
local keys = require('pckr.loader.keys')
pckr.add{
 {"my/plugin", cond = keys('n', 'ga') },
}

Automatically find local plugins

This snippet can be used to automatically detect local plugins in a particular directory.

local local_plugin_dir = vim.env.HOME..'/projects/'
local function resolve(x)
 if type(x) == 'string' and x:sub(1, 1) ~= '/' then
 local name = vim.split(x, '/')[2]
 local loc_install = vim.fs.join_paths(local_plugin_dir, name)
 if name ~= '' and vim.fn.isdirectory(loc_install) == 1 then
 return loc_install
 end
 end
end
local function try_get_local(spec)
 if type(spec) == 'string' then
 return resolve(spec) or spec
 end
 if not spec or type(spec[1]) ~= 'string' then
 return spec
 end
 return resolve(spec[1]) or spec[1]
end
local function walk_spec(spec, field, fn)
 if type(spec[field]) == 'table' then
 for j in ipairs(spec[field]) do
 walk_spec(spec[field], j, fn)
 end
 walk_spec(spec[field], 'requires', fn)
 end
 spec[field] = fn(spec[field])
end
local init {
 'nvim-treesitter/nvim-treesitter'
 -- plugins spec
}
walk_spec({init}, 1, try_get_local)
require('pckr').add(init)

Debugging

pckr.nvim logs to stdpath(cache)/pckr.nvim.log. Looking at this file is usually a good start if something isn't working as expected.

About

Spiritual successor of https://github.com/wbthomason/packer.nvim

Topics

Resources

License

Stars

Watchers

Forks

Packages

Contributors

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /