abeldekat / lazyflex.nvim

An addon for lazy.nvim. Easily enable/disable multiple plugins.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

lazyflex.nvim

Update: This repository has been archived on 20240329

lazyflex.nvim is an add-on for lazy.nvim, a modern plugin manager for Neovim.

Its main objective is to make it easier to test and troubleshoot a Neovim configuration.

Demo

demo.mp4

The code used in the demo can be found here

Features

  • Easier troubleshooting/testing from one central location.
    • Enable/disable multiple plugins by keyword.
    • Define and use custom presets for your own configuration.
    • Has presets for each default plugin module in LazyVim.
    • Has options to skip loading the configuration modules (options, autocmds, keymaps) provided by LazyVim
  • Helps to verify the independence of the components in the configuration.
  • When creating an issue, facilitates writing a concise reproducible configuration.
    • Contains examples for minimal configurations using lazyflex.

Requirements

References:

Installation

The plugin must be the first item in the spec!

require("lazy").setup({
  spec = {
    {
      "abeldekat/lazyflex.nvim",
      version = "*",
      cond = true,
      import = "lazyflex.hook",
      opts = {},
    },
    -- your plugins:
    -- { "LazyVim/LazyVim", import = "lazyvim.plugins" },
    -- { import = "plugins" },
  },
})

Note: The cond property in the snippet above is practical for quickly toggling lazyflex on or off, whilst still keeping the plugin installed. Lazyflex is heavily optimized, and can also be kept enabled.

Note: It is not possible to configure multiple fragments of the plugin.

Note: See examples/lazyflex_spec.lua for a more complete lazyflex spec.

References:

Concepts

lazyflex:

  1. Returns immediately when there are no keywords or presets supplied to enable or disable
  2. Only operates on plugins that are not unconditionally disabled(plugin.enabled = false)

Important properties

  • filter_modules.kw: when enabled, only import a selection of the modules in use, thereby reducing the number of plugins to consider. See lazy.nvim's import
  • kw: a list of words matching names of plugins.
  • preset: a predefined list of words matching names of plugins
  • enable_match:
    • true(enable incrementally, default): enable all plugins that match keywords, disable the others.
    • false(disable incrementally): disable all plugins that match keywords, enable the others
  • override_kw: invert enable_match on a plugin when its name has a match in both this list of words and in kw including presets

When using presets: References to a non-existing preset will be ignored.

Colorscheme

Important: The name of the colorscheme must be in the keywords when enable_match = true

Approaches:

  1. Add the name to property kw in the opts: kw = { "toky" }
  2. Add the name to property kw_always_enable in the opts: kw_always_enable = { "toky" }
  3. When using LazyVim: Use the colorscheme preset.
  4. When using custom presets: Create a colorscheme preset.

Use cases

Using a personal configuration

The plugin can be used when the user's configuration is not build upon a community setup like LazyVim. It is possible to configure custom presets.

Using a community setup like LazyVim

Prerequisite: Add the LazyVim plugin

Reusing specs from a collection of plugins

LazyVim can be used without loading its options, autocommands or keymappings. The settings of the resulting configuration will default to stock Neovim.

Scenario's where this can be useful:

Prerequisite: Add the LazyVim plugin

Add to opts:

lazyvim = { settings = { enabled = false } }

Examples

  -- Enable harpoon, plenary and tokyonight. Disable all other plugins.
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = { kw = { "har", "plen", "tokyo" } },
  },

  -- Disable telescope and harpoon. Enable: all other plugins.
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = { enable_match = false, kw = { "tele", "har" } },
  },

  -- Only use lazy.nvim, LazyVim, and tokyonight, without LazyVim's settings.
  -- An alternative would be a lazy.nvim spec, addding tokyonight.
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = {
      lazyvim = { settings = { enabled = false } },
      kw = { "tokyo" },
    },
  },

  -- All plugins except the ones defined in LazyVim's ui module
  -- Plugins: approximately 10 disabled
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = {
      lazyvim = { presets = { "ui" } },
      enable_match = false,
    },
  },

  -- Enable plugins in LazyVim's editor module and plugins matching `cmp`,
  -- except nvim-spectre(editor), flash.nvim(editor) and cmp_luasnip
  -- Plugins: approximately 30 disabled
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = {
      lazyvim = { presets = { "editor" } },
      kw = { "tokyo", "cmp" },
      override_kw = { "spectre", "fla", "luasn" },
    },
  },

  -- Enable all plugins, excluding plugins from other modules than
  -- either "lazyvim.plugins" or "plugins"
  -- To do this manually, one would need to comment out all "other" imports...
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = {
      filter_modules = { enabled = true },
      enable_match = false,
    },
  },

  -- Enable the minimal amount of plugins needed for running neotest-python
  {
    "abeldekat/lazyflex.nvim",
    import = "lazyflex.hook",
    opts = {
      filter_modules = { enabled = true, kw = { "py", "test" } },
      lazyvim = { presets = { "treesitter"} },
      kw = { "toky", "test", "plen" },
    },
  },

Configuration

lazyflex.nvim comes with the following defaults:

{
  -- when enabled: only import a selection of the modules in use
  filter_modules = {
    enabled = false,
    kw = {}, -- contains keywords for module names to import
    always_import = {}, -- always contains "lazyvim.plugins" and "plugins"
  },

  lazyvim = {
    presets = {}, -- example: { "coding" }: matches all plugins in the coding module

    settings = { -- load lazyvim's settings by default:
      enabled = true, -- quick switch. Disables the three options below:
      options = true, -- use config.options
      autocmds = true, -- use config.autocmds
      keymaps = true, -- use config.keymaps
    },
  },

  user = {
    -- optional: functions implementing presets and change_settings
    get_preset_keywords = nil,
    change_settings = nil,

    presets = {}, -- example, when implemented: { "editor" }

    settings = { -- passed into function change_settings:
      enabled = true, -- quick switch. Disables the three options below:
      options = true,
      autocmds = true,
      keymaps = true,
    },
  },

  -- either enable or disable matching plugins:
  enable_match = true,

  -- keywords matching plugins to always enable:
  kw_always_enable = {}, -- the "lazy" keyword is always included

  -- keywords matching plugins, as specified by the user:
  kw = {}, -- example: "line" matches lualine, bufferline and indent-blankline

  -- when the name of a plugin is matched and also has a match in override_kw:
  -- invert enable_match for that plugin
  override_kw = {},
}

Custom presets and settings

As an optional step, the user can add custom functions for handling presets and changing settings to the user section in opts. The following functions are used by lazyflex:

  • presets: get_preset_keywords(name, enable_match)
    • name: the name of the preset
    • enable_match: true when enabling, false otherwise
    • returns: a list with keywords or {}
  • settings: change_settings(settings)
    • settings: the settings provided in opts
    • returns: a spec(used by LazyVim) or {}

These functions can be implemented in a separate module in the user's configuration.

Suggestion: Copy the example module examples/lazyflex_collection.lua to the lua folder inside XDG_CONFIG_HOME. On linux, XDG_CONFIG_HOME defaults to ~/.config/nvim

Note: Do not use a folder lazy.nvim is configured to import from.

Example user opts:

user = {
  get_preset_keywords = require("lazyflex_collection").get_preset_keywords,
  change_settings = require("lazyflex_collection").change_settings,
  presets = {},
  settings = {},
},

Minimal reproducible configurations

There are two examples for writing reproducible configurations using lazyflex:

Lazyflex starter

When starting Neovim for the first time, lazyflex.nvim is not present yet. As a consequence, plugins will be cloned before lazyflex.nvim is activated.

It is possible to avoid cloning plugins that will be not be enabled by cloning lazyflex.nvim first.

See lazyflex starter, a modified LazyVim starter

About enabling and disabling

For each plugin managed by lazy.nvim that is not unconditionally disabled, lazyflex overrides its cond property.

The cond property needs to be set before lazy.nvim starts taking its value into consideration. Therefore, lazyflex operates in the "spec phase". As part of the "spec phase", lazy.nvim requires lazyflex.hook

See: :Lazy profile.

A similar approach can also be found in the following code:

References:

History

The idea grew over time:

Acknowledgements

  • lazy.nvim: The architecture, semantics and enhanced possibilities.
  • LazyVim: The concept of a plugin as a collection of other plugins.

About

An addon for lazy.nvim. Easily enable/disable multiple plugins.

License:Apache License 2.0


Languages

Language:Lua 96.3%Language:Shell 3.7%