hollow.plugins

June 4, 2026 · View on GitHub

Declare, autoload, and update plugins.

For the conceptual model see Plugins. For a working example see examples/plugins/hollow-spirit.

Functions

hollow.plugins.setup(config?)   -- install + autoload + call setup()
hollow.plugins.sync()           -- git pull --ff-only for all git plugins

setup

hollow.plugins.setup({
  plugins = {
    "user/repo",                                                -- github short form
    { "user/repo", opts = { ... } },                            -- with opts
    "https://gitlab.com/user/repo",                             -- any git URL
    "~/my-local-plugin",                                        -- local path (~)
    { "/absolute/path/to/plugin", opts = { ... } },             -- local absolute
  },
})

For each entry, the loader:

  1. Normalizes the spec (path, source, opts, url).
  2. For git specs: clones into data_dir()/plugins/<repo> if missing.
  3. Prepends the plugin's lua/ to package.path.
  4. Sources every hollow_plugin/*.lua file.
  5. Calls M.setup(opts) on the module named by the last path component, if it exists.

A failed clone or autoload file never aborts startup; the loader logs and continues.

sync

hollow.plugins.sync()

For each plugin with a .git directory, runs git pull --ff-only --recurse-submodules and logs the result. Restart Hollow to pick up new code.

Plugin layout

my-plugin/
  lua/                       -- added to package.path
    my-plugin/
      init.lua               -- exposes M.setup(opts) if configurable
  hollow_plugin/             -- autoloaded
    my-plugin.lua            -- or hollow_plugin/my-plugin/init.lua
  • lua/ is for on-demand require().
  • hollow_plugin/ is for keymaps, event listeners, command registration. Sourced unconditionally in alphabetical order.
  • setup() is optional.

Errors and recovery

SituationBehaviour
Git clone failsLogged, plugin skipped, others continue
hollow_plugin/*.lua errorsLogged, loader continues with the next file
require() of the module failsSilently skipped (plugin may be autoload-only)
setup() throwsLogged with traceback, loader continues
Local path missingLogged, plugin skipped

Out of scope (v1)

  • Package manager UI
  • Plugin-to-plugin dependency declarations
  • Lazy loading
  • Version pinning (tag, commit)
  • Lockfiles

See also