wbthomason / packer.nvim

A use-package inspired plugin manager for Neovim. Uses native packages, supports Luarocks dependencies, written in Lua, allows for expressive config
MIT License
7.89k stars 264 forks source link

Feature Request: Blocking Install #198

Open jzelinskie opened 3 years ago

jzelinskie commented 3 years ago

I'm trying to be clever while bootstrapping the first run of neovim to install packer. I'd actually like to block during install so that I don't get any errors when the rest of my config is loaded after kicking off the packer.install().

cwebster2 commented 3 years ago

Seconding This. What i'd love to do is be able to run nvim --headless +PackerSync +qa in my env installer script.

wbthomason commented 3 years ago

Making a blocking install is more involved than it seems on its face, because the jobs we rely on are inherently non-blocking. We could use busy-waiting (e.g. a loop until the job done callback gets invoked), but that seems undesirable. I could be wrong, but I don't believe we have access to any of the usual synchronization primitives to block without spinning.

I'll need to think about the best way to do this - contributions or suggestions are welcome!

wbthomason commented 3 years ago

Note to myself/anyone who wants to take this issue on: vim.wait might provide a good way to make things block without spinning.

nanotee commented 3 years ago

I believe these use cases have been addressed at least in part with #259

Bootstrapping packer + plugins in init.lua without errors ```lua local fn = vim.fn -- Auto install packer.nvim local install_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim' if fn.isdirectory(install_path) == 0 then fn.system({'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path}) require('plugin_specification') vim.cmd 'autocmd User PackerComplete ++once lua require("my_config")' require('packer').sync() else require('my_config') end ```
Bootstrapping packer + plugins in a shell script ```sh #!/usr/bin/env sh install_packer() { PACKER_DIRECTORY="${XDG_DATA_HOME:-$HOME/.local/share}/nvim/site/pack/packer/start/packer.nvim" if ! [ -d "$PACKER_DIRECTORY" ]; then git clone "https://github.com/wbthomason/packer.nvim" "$PACKER_DIRECTORY" fi } bootstrap_plugins() { nvim -u NONE \ +'autocmd User PackerComplete quitall' \ +'lua require("plugin_specification")' \ +'lua require("packer").sync()' } install_packer bootstrap_plugins ```

I can open a PR to add these snippets to the README if you find them useful.

wbthomason commented 3 years ago

I think it may be time to move information like this to a FAQ or wiki; the README is already cumbersome. I agree that #259 provides a reasonable mechanism for this behavior, though.

2deth commented 3 years ago

my script for updating plugins from shell(fish):

  nvim \
    +'autocmd User PackerComplete sleep 100m | write ~/.packer.sync.result | qall' \
    +PackerSync
  cat ~/.packer.sync.result | rg -v 'Press'

(or any better | simpler way?)

petertriho commented 3 years ago

Does this https://github.com/wbthomason/packer.nvim/issues/106 not work anymore? (I can't seem to get it to work nvim --headless +PackerSync +qa doesn't update plugins)

wbthomason commented 3 years ago

@petertriho: Do you encounter errors, or does it just silently fail?

petertriho commented 3 years ago

Silently fails, pretty much doesn't do anything (doesn't update plugins)

wbthomason commented 3 years ago

@petertriho: I think this is related to packer.clean being made async since #106. However, it's likely that the sync operation was never fully working - probably just fired off the various git processes and then Neovim exited. For now, @2deth's comment above is the best way to do blocking headless install.

cloudlena commented 3 years ago
$ nvim --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync'

seems to work

bangedorrunt commented 3 years ago

@mastertinner, I used your snippet but it complained E492: Not an editor command

Cloning into '/Users/tdt/.local/share/nvim/site/pack/packer/start/packer.nvim'...
remote: Enumerating objects: 2501, done.
remote: Counting objects: 100% (805/805), done.
remote: Compressing objects: 100% (259/259), done.
remote: Total 2501 (delta 608), reused 685 (delta 536), pack-reused 1696
Receiving objects: 100% (2501/2501), 773.73 KiB | 4.99 MiB/s, done.
Resolving deltas: 100% (1407/1407), done.
Error detected while processing command line:
E492: Not an editor command: PackerSync
Press ENTER or type command to continue
cloudlena commented 3 years ago

hmm, possibly, neovim needs to be restarted after installing packer before you have access to it... depends a bit on your setup

bangedorrunt commented 3 years ago

@mastertinner sorry, I asked too quick, just found out I got my plugins loaded in vim.defer_fn, which caused the issue. Add -c 'sleep 1' or moved my plugins out of defer function fixed the problem!

hermitmaster commented 1 year ago
$ nvim --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync'

seems to work

I've been using this method, but PackerComplete doesn't wait (block) for hooks. Thus, plugins like Mason and treesitter aren't finished before PackerComplete fires.

carschandler commented 1 year ago

I believe these use cases have been addressed at least in part with #259 Bootstrapping packer + plugins in init.lua without errors

local fn = vim.fn

-- Auto install packer.nvim
local install_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim'

if fn.isdirectory(install_path) == 0 then
  fn.system({'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path})
  require('plugin_specification')
  vim.cmd 'autocmd User PackerComplete ++once lua require("my_config")'
  require('packer').sync()
else
  require('my_config')
end

Bootstrapping packer + plugins in a shell script

I can open a PR to add these snippets to the README if you find them useful.

Hi @nanotee, I'm looking to implement this into my nvim config. What exactly are the differences between plugin_specification and my_config here?

EDIT: I figured it out. plugin_specification would be your typical plugins.lua file that you'd find in the Quickstart section of packer's README. **Note that it is required that you include the vim.cmd [[packadd packer.nvim]]line at the beginning of your plugins.lua and before any call to require('packer') is made. The file in the README says that it is only mandatory if you have configured packer to be opt, but to bootstrap, it is required. Once you've set up your plugins.vim, you can work on the my_config part, which is whatever lua calls you'd want to make AFTER packer has installed/sync'd all your plugins. For me, I made it a require('user/post_packer_init') (where the file for this is .config/nvim/lua/user/post_packer_init.lua) and finally from there I require('user/colors') and require('user/completion') where I have my package-dependent configuration (i.e. I configure gruvbox.nvim in users/colors.lua which wouldn't work unless packer had finished installing it first).