avataralpha2phi

Summary

This context provides a guide on managing Neovim packages using a plugin or package manager, specifically focusing on the use of packer.nvim.

Abstract

The context begins by explaining the XDG base directory and how Neovim uses the XDG_CONFIG_HOME and XDG_DATA_HOME environment variables for configuration and data directories. It then delves into the concept of Neovim packages and how they are installed under the $XDG_DATA_HOME directory. The text explains how packer.nvim, a Lua plugin built on the package feature, simplifies package management. The guide further discusses profiling to monitor and profile plugins, lazy loading plugins for better startup performance, and the different options to achieve this using packer.nvim. It also provides examples of how to lazy load plugins using cmd and event options. The context concludes by mentioning other features of packer.nvim and encourages readers to explore the documentation for more information.

Bullet points

  • The guide begins with an explanation of the XDG base directory and how Neovim uses the XDG_CONFIG_HOME and XDG_DATA_HOME environment variables.
  • Neovim packages are installed under the $XDG_DATA_HOME directory.
  • Packer.nvim is a Lua plugin built on the package feature to simplify package management.
  • Profiling is set up to monitor and profile plugins using packer.nvim.
  • Lazy loading plugins is discussed as a method to improve startup performance.
  • The guide provides examples of how to lazy load plugins using cmd and event options.
  • Other features of packer.nvim are mentioned, and readers are encouraged to explore the documentation for more information.

Neovim for Beginners —Plugin Management

Manage Neovim packages using a plugin or package manager.

Neovim for Beginners — Plugin Management

Let’s understand Neovim packages (:h packages), and see how to properly manage them using a plugin/package manager (packer.nvim).

We are going to

  • Understand how packages work in Neovim.
  • Configure profiling to monitor and profile the plugins.
  • Understand the different options to lazy load plugins for better startup performance.
  • Lazy load plugins using different options.
  • Configure other useful plugins and lazy load them.

This article is part of the Neovim for Beginners series.

The Neovim configuration files can be found in this repository.

Packages

Let’s begin with the XDG base directory.

Neovim uses the $XDG_CONFIG_HOME and $XDG_DATA_HOME environment variables if they exist.

  • For Linux/Unix, the$XDG_CONFIG_HOME configuration directory defaults to ~/.config and~/.config/nvim. In Windows, it defaults to ~/AppData/Local ~/AppData/Local/nvim.
  • For the data directory $XDG_DATA_HOME, in Linux/Unix it defaults to ~/.local/share and ~/.local/share/nvim. In Windows, it defaults to ~/AppData/Local and ~/AppData/Local/nvim-data.

Neovim plugins or packages are installed under the$XDG_DATA_HOME directory. For our configuration, we explicitly specify the location of the$XDG_DATA_HOME in our installation script.

NVIM_BEGINNER=~/.config/nvim-beginner
export NVIM_BEGINNER
rm -rf $NVIM_BEGINNER
mkdir -p $NVIM_BEGINNER/share
mkdir -p $NVIM_BEGINNER/nvim
stow --restow --target=$NVIM_BEGINNER/nvim .
alias nvb='XDG_DATA_HOME=$NVIM_BEGINNER/share XDG_CONFIG_HOME=$NVIM_BEGINNER nvim'
export nvb
  • In the lua/plugins.lua file, we specify the installation path ofpacker.nvim to be under $XDG_DATA_HOME/site/pack/packer/start.
local install_path = fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim"
$XDG_DATA_HOME
  • Plugins under the start folder are loaded automatically (:h packages) whereas plugins under opt folder are loaded optionally (:h pack-add).

Neovim packages is a built-in feature and packer.nvim is a Lua plugin built on this feature to make package management easier for us.

From the documentation,

A Vim package is a directory that contains one or more plugins. The advantages over normal plugins:

  • A package can be downloaded as an archive and unpacked in its own directory. Thus the files are not mixed with files of other plugins. That makes it easy to update and remove.
  • A package can be a git, mercurial, etc. repository. That makes it really easy to update.
  • A package can contain multiple plugins that depend on each other.
  • A package can contain plugins that are automatically loaded on startup and ones that are only loaded when needed with “:packadd”.

Let’s continue to see how packer.nvim can help us manage the packages.

Profiling

Let’s set up profiling to help us monitor and profile the plugins.

In lua/plugins.lua, add the following packer.nvim configuration.

local conf = {
  profile = {
    enable = true,
    threshold = 0, -- the amount in ms that a plugins load time must be over for it to be included in the profile
  },
  display = {
    open_fn = function()
     return require("packer.util").float { border = "rounded" }
    end,
  },
}

To optimize startup time, packer.nvim compiles code to perform the lazy-loading operations you specify.

Run :PackerCompile to make sure we generate the compiled loader file (packer_compiled.lua).

Restart Neovim and then type :PackerProfile.

Profiling using packer.nvim

We can see the configured plugins are loaded automatically on startup, and all of them are under the $XDG_DATA_HOME start folder. E.g. the Neogit plugin takes 13ms to load.

$XDG_DATA_HOME

Package Management

Lazy Loading

For better startup performance, we should load the plugins or packages when they are needed. packer.nvim supports multiple options to lazy load plugins.

  • cmd: Specifies commands which load this plugin. Can be anautocmd pattern.
  • ft: Specifies filetypes that load this plugin.
  • keys: Specifies maps that load this plugin.
  • event: Specifies autocommand events that load this plugin.
  • fn: Specifies functions that load this plugin.
  • cond: Specifies a conditional test to load this plugin.
  • module: Specifies Lua module names for require. When requiring a string that starts with one of these module names, the plugin will be loaded.
  • module_pattern: Specifies the Lua pattern of Lua module names for require. When requiring a string that matches one of these patterns, the plugin will be loaded.

Lazy Loading using cmd

For our Neogit plugin, let’s change it so that it loads only when the Neogit command is triggered.

In lua/plugins.lua, add the line to load Neogit only when the command is triggered.

use {
   "TimUntersberger/neogit",
   cmd = "Neogit",
   requires = "nvim-lua/plenary.nvim",
     config = function()
       require("config.neogit").setup()
   end,
}

We configured the autocmd to compile plugins.lua automatically so it is not necessary to run :PackerCompile. However, if the change is not taking effect, try manually compiling the loader file.

Restart Neovim and run :PackerProfile.

Profiling using packer.nvim

You can see the Neogit plugin is not loaded now. In the $XDG_DATA_HOMEfolder, it is now under the opt folder (previously it is under the start folder).

$XDG_DATA_HOME

Try running the :Neogit command and the Neogit plugin should get lazy-loaded.

Lazy Loading using event

Let’s try to lazy load plugins using the event option.

-- WhichKey
use {
  "folke/which-key.nvim",
   event = "VimEnter",
   config = function()
    require("config.whichkey").setup()
   end,
}
-- IndentLine
use {
  "lukas-reineke/indent-blankline.nvim",
  event = "BufReadPre",
  config = function()
    require("config.indentblankline").setup()
  end,
}
  • We configure the WhichKey plugin to load upon the VimEnter(:h VimEnter) event.
  • We configure the Indent-BlankLine plugin to load upon the BufReadPre (:h BufReadPre) event.

Restart Neovim and run :PackerProfile. Only the color scheme and startup screen plugins are loaded now.

Profiling using packer.nvim
$XDG_DATA_HOME

Lazy Loading Other Plugins

We are going to install the following plugins and lazy load them.

For plenary.nvim, we also change it to lazy load when “require”.

In lua/plugins.lua add the plugins.

  • Run :PackerInstall to install the plugins.
  • Restart Neovim and run :PackerProfile. You can see the startup performance is not impacted.
Profiling using packer.nvim

All the plugins are in the $XDG_DATA_HOME opt folder.

$XDG_DATA_HOME

Run :PackerStatus to see the statuses of the plugins.

Plugin Status using packer.nvim

Exercise for you — try triggering the command or key to load the plugins and run :PackerStatus again.

Other Features

There are many more features that packer.nvim provides. We can optionally disable a plugin, tag the plugin to a particular commit/tag/branch, run a post-update/install hook, etc. Check out the documentation to experiment with them.

Check out Learn Neovim The Practical Way for all the Vim/Neovim articles!

If you are not a Medium member yet and want to become one, click here. (A part of your subscription fee will be used to support alpha2phi.)

Neovim
Vim
Hacking
Coding
Programming
Recommended from ReadMedium