Packer.nvim: Bootstrapping packer

Created on 23 Sep 2020  路  10Comments  路  Source: wbthomason/packer.nvim

I've seen several questions about how to do an unsupervised installation of neovim (not all specific to packer); a core question here is how to ensure from your init.vim that all your plugins are installed on a fresh system.

Vim-plug has this suggestion, and it would be nice to provide a similar snippet for packer.nvim that people can just put into their init.vim/init.lua. If there is something that can be implemented in neovim core to make this smoother, this might also be considered?

documentation enhancement good first issue help wanted

Most helpful comment

Thanks for the fixes! Sorry I dropped off when I was supposed to be testing stuff...

All 10 comments

I just saw this discussion in Gitter; I love the idea. I'd be happy to accept a PR for this - otherwise, I'll sketch up a snippet myself (shouldn't be too involved - maybe validate requirements (i.e. do you have git, is your Neovim built with LuaJIT, etc.), run a git clone, make sure rtp (and therefore package.path) has the right directory on it)

It's a bit of annoying duplication, but it might be worthwhile to write both Vimscript and Lua snippets.

Pardon my ignorance, but is git clone followed by nvim +PackerCompile +PackerSync not enough?

Note that the "Quitting Packer too fast?" bug is annoying here because you can't just automate this in a Bash script:

packer_dir="$HOME/.local/share/nvim/site/pack/packer/opt"
mkdir -p "$packer_dir"
git clone --single-branch https://github.com/wbthomason/packer.nvim "${packer_dir}/packer.nvim"
nvim +PackerCompile +PackerSync

@gwerbin That should be fine, but many people like to have code to bootstrap their plugin setup in their init.vim.

I have this in my plugins.lua, which is sourced by my init.vim:

local execute = vim.api.nvim_command
local fn = vim.fn

local install_path = fn.stdpath('data')..'/site/pack/packer/opt/packer.nvim'

if fn.empty(fn.glob(install_path)) > 0 then
    execute('!git clone https://github.com/wbthomason/packer.nvim '..install_path)
end

execute 'packadd packer.nvim'

Still have to PackerCompile/etc though.

@Iron-E: would it be OK if I adopted that (with credit) for use in the README as a suggested bootstrap snippet? It's one of the cleanest I've come across.

Feel free!

Great, thank you!

Thanks for the fixes! Sorry I dropped off when I was supposed to be testing stuff...

If anyone comes across this and would like to follow the _Lua_ path, here's how I do it. You'd need to put this somewhere on your :h runtimepath, in my case lua/pack/init.lua, then to setup your packages, just call require('pack').

-- Rudamentary logging, just use `vlog.nvim` and save yourself the trouble,
-- but its here if you want it
local echohl = vim.schedule_wrap(
    function(msg, hl)
        local emsg = vim.fn.escape(msg, '"')
        vim.cmd('echohl ' .. hl .. ' | echom "' .. emsg .. '" | echohl None')
    end
)

local info = function(msg) echohl(msg, 'None') end
local err = function(msg) echohl(msg, 'ErrorMsg') end

local function init(success)
    if not success then
        err('[packer]: Failed setup')
        return
    end

    info('[packer]: Loading package list')
    vim.cmd('packadd packer.nvim')

    -- Uncomment/change this depending on where you want your 'list' of packages
    -- to load from
    --
    -- This would be somewhere on your `:h runtimepath`, and would likely contain
    -- a call to `startup` provided by `packer`
    -- require('pack.list')
end

local function bootstrap()
    -- Bootstrap `packer` installation to manage packages
    local packer = {
        path = vim.fn.stdpath('data') .. '/site/pack/packer/opt/packer.nvim',
        url = 'https://github.com/wbthomason/packer.nvim'
    }

    if vim.fn.executable('git') ~= 1 then
        err('[packer] Bootstrap failed, git not installed')
        return
    end

    if vim.fn.empty(vim.fn.glob(packer.path)) > 0 then
        info('[packer]: Installing...')

        local handle
        handle = vim.loop.spawn(
            'git',
            {
                args = {
                    'clone',
                    packer.url,
                    packer.path,
                },
            },
            vim.schedule_wrap(
                function(code, _)
                    -- Wrapper to call `init` based on the success of the above `git` operation
                    handle:close()
                    init(code == 0)
                end
            )
        )
    else
        -- `packer` already installed, continue to load package list
        init(true)
    end
end

bootstrap()
Was this page helpful?
0 / 5 - 0 ratings

Related issues

akinsho picture akinsho  路  9Comments

GustavoPrietoP picture GustavoPrietoP  路  7Comments

YaBoiBurner picture YaBoiBurner  路  4Comments

clason picture clason  路  5Comments

nanotee picture nanotee  路  7Comments