From 3d77e4514e3ed21e00c68d3c416f2f37b627b904 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 23 Jun 2024 10:09:41 +0200 Subject: [PATCH] docs: updated --- .markdownlint.yaml | 14 +++ docs/configuration/index.md | 14 +++ docs/developers.md | 7 +- docs/installation.md | 51 ----------- docs/installation.mdx | 169 ++++++++++++++++++++++++++++++++++++ docs/packages.md | 28 ++++++ docs/spec/index.md | 94 +++++++++++++------- docs/spec/lazy_loading.md | 20 +++-- docs/usage/index.md | 141 ++++++++---------------------- docs/usage/lockfile.md | 4 +- docs/usage/profiling.md | 8 +- docs/usage/structuring.md | 66 ++++++++++++++ lua/build.lua | 103 +++++++++++++--------- lua/init.lua | 62 ++++++------- lua/tpl/install.lua | 46 ++++++++++ stylua.toml | 6 ++ 16 files changed, 565 insertions(+), 268 deletions(-) create mode 100644 .markdownlint.yaml delete mode 100644 docs/installation.md create mode 100644 docs/installation.mdx create mode 100644 docs/usage/structuring.md create mode 100644 lua/tpl/install.lua create mode 100644 stylua.toml diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..ef9d57a --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,14 @@ +MD013: + line_length: 120 + tables: false +MD033: + allowed_elements: + - "Tabs" + - "TabItem" + - "details" + - "summary" + - "b" + - "table" + - "tr" + - "td" + - "a" diff --git a/docs/configuration/index.md b/docs/configuration/index.md index 558828e..9ea6f7c 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -35,6 +35,20 @@ sidebar_position: 5 -- increase downloads a lot. filter = true, }, + pkg = { + enabled = true, + cache = vim.fn.stdpath("state") .. "/lazy/pkg-cache.lua", + versions = true, -- Honor versions in pkg sources + sources = { + "lazy", + "rockspec", + "packspec", + }, + }, + rocks = { + root = vim.fn.stdpath("data") .. "/lazy-rocks", + server = "https://nvim-neorocks.github.io/rocks-binaries/", + }, dev = { ---@type string | fun(plugin: LazyPlugin): string directory where you store your local plugin projects path = "~/projects", diff --git a/docs/developers.md b/docs/developers.md index 67a254d..f3df19d 100644 --- a/docs/developers.md +++ b/docs/developers.md @@ -3,8 +3,11 @@ sidebar_position: 7 --- # 📚 Plugin Developers -If your plugin needs a build step, you can create a file `build.lua` or `build/init.lua` -in the root of your repo. This file will be loaded when the plugin is installed or updated. +To make it easier for users to install your plugin, you can include a [package spec](/packages) in your repo. + +If your plugin needs a build step, you can specify this in your **package file**, +or create a file `build.lua` or `build/init.lua` in the root of your repo. +This file will be loaded when the plugin is installed or updated. This makes it easier for users, as they no longer need to specify a `build` command. diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index 0da62ad..0000000 --- a/docs/installation.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -sidebar_position: 2 ---- -# đŸ”Ĩ Installation - -You can add the following Lua code to your `init.lua` to bootstrap **lazy.nvim**: - - - -```lua title="lua/config/lazy.lua" -local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" -if not (vim.uv or vim.loop).fs_stat(lazypath) then - vim.fn.system({ - "git", - "clone", - "--filter=blob:none", - "https://github.com/folke/lazy.nvim.git", - "--branch=stable", -- latest stable release - lazypath, - }) -end -vim.opt.rtp:prepend(lazypath) -``` - - - -Next step is to add **lazy.nvim** below the code added in the prior step in `init.lua`: - -```lua -require("lazy").setup(plugins, opts) -``` - -- **plugins**: this should be a `table` or a `string` - - `table`: a list with your [Plugin Spec](#-plugin-spec) - - `string`: a Lua module name that contains your [Plugin Spec](#-plugin-spec). See [Structuring Your Plugins](#-structuring-your-plugins) -- **opts**: see [Configuration](#%EF%B8%8F-configuration) **_(optional)_** - -```lua --- Example using a list of specs with the default options -vim.g.mapleader = " " -- Make sure to set `mapleader` before lazy so your mappings are correct -vim.g.maplocalleader = "\\" -- Same for `maplocalleader` - -require("lazy").setup({ - "folke/which-key.nvim", - { "folke/neoconf.nvim", cmd = "Neoconf" }, - "folke/neodev.nvim", -}) -``` - -ℹī¸ It is recommended to run `:checkhealth lazy` after installation. - diff --git a/docs/installation.mdx b/docs/installation.mdx new file mode 100644 index 0000000..b99147c --- /dev/null +++ b/docs/installation.mdx @@ -0,0 +1,169 @@ +--- +sidebar_position: 2 +--- +# 🛠ī¸ Installation + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +There are multiple ways to install **lazy.nvim**. +The **Structured Setup** is the recommended way, but you can also use the **Single File Setup** +if you prefer to keep everything in your `init.lua`. + +Please refer to the [Configuration](/configuration) section for an overview of all available options. + +:::tip + +It is recommended to run `:checkhealth lazy` after installation. + +::: + +:::note + +In what follows `~/.config/nvim` is your Neovim configuration directory. +To know the correct path for your system, run `:echo stdpath('config')`. + +::: + + + + +```lua title="~/.config/nvim/init.lua" +require("config.lazy") +``` + + + +```lua title="~/.config/nvim/lua/config/lazy.lua" +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` before loading lazy.nvim +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = " " -- Make sure to set `mapleader` before lazy so your mappings are correct +vim.g.maplocalleader = "\\" -- Same for `maplocalleader` + +-- Setup lazy.nvim +require("lazy").setup({ + -- highlight-start + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- highlight-end + defaults = { + -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. + -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. + lazy = false, + -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, + -- have outdated releases, which may break your Neovim install. + version = false, -- always use the latest git commit + -- version = "*", -- try installing the latest stable version for plugins that support semver + }, + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + checker = { enabled = true }, -- automatically check for plugin updates + performance = { + rtp = { + -- uncomment the below to disable some rtp plugins + disabled_plugins = { + -- "gzip", + -- "matchit", + -- "matchparen", + -- "netrwPlugin", + -- "tarPlugin", + -- "tohtml", + -- "tutor", + -- "zipPlugin", + }, + }, + }, +}) +``` + + + +You can then create your plugin specs in `lua/plugins`. +Each file should return a table with the plugins you want to install. + +For more info see [Structuring Your Plugins](/usage/structuring) + + +
+~/.config/nvim
+├── lua
+│   ├── config
+│   │   └── lazy.lua
+│   └── plugins
+│       ├── spec1.lua
+│       ├── **
+│       └── spec2.lua
+└── init.lua
+
+ + +
+ + + +```lua title="~/.config/nvim/init.lua" +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` before loading lazy.nvim +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = " " -- Make sure to set `mapleader` before lazy so your mappings are correct +vim.g.maplocalleader = "\\" -- Same for `maplocalleader` + +-- Setup lazy.nvim +require("lazy").setup({ + -- highlight-start + spec = { + -- add your plugins here + }, + -- highlight-end + defaults = { + -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. + -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. + lazy = false, + -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, + -- have outdated releases, which may break your Neovim install. + version = false, -- always use the latest git commit + -- version = "*", -- try installing the latest stable version for plugins that support semver + }, + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + checker = { enabled = true }, -- automatically check for plugin updates + performance = { + rtp = { + -- uncomment the below to disable some rtp plugins + disabled_plugins = { + -- "gzip", + -- "matchit", + -- "matchparen", + -- "netrwPlugin", + -- "tarPlugin", + -- "tohtml", + -- "tutor", + -- "zipPlugin", + }, + }, + }, +}) +``` + + + + +
+ diff --git a/docs/packages.md b/docs/packages.md index 94d14f4..9e71ece 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -3,3 +3,31 @@ sidebar_position: 4 --- # đŸ“Ļ Packages +**lazy.nvim** supports three ways for plugins to define their dependencies and configuration. + +- **Lazy**: `.lazy.lua` file +- **Rockspec**: [luarocks](https://luarocks.org/) `*-scm-1.rockspec` [file](https://github.com/luarocks/luarocks/wiki/Rockspec-format) +- **Packspec**: `pkg.json` (experimental, since the [format](https://github.com/neovim/packspec/issues/41) is not quite there yet) + +:::info + +Package specs are always loaded in the scope of the plugin (using [specs](/spec#advanced)), +so that when the plugin is disabled, none of the specs are loaded. + +::: + +## Lazy + +Using a `.lazy.lua` file is the recommended way to define your plugin dependencies and configuration. +Syntax is the same as any plugin spec. + +## Rockspec + +When a plugin contains a `*-scm-1.rockspec` file, **lazy.nvim** will automatically load its [`rocks`](/spec#setup) dependencies. + +## Packspec + +Supports the [pkg.json](https://github.com/nvim-lua/nvim-package-specification/issues/41) format, +with a lazy extension in `lazy`. +`lazy` can contain any valid lazy spec fields. They will be added to the plugin's spec. + diff --git a/docs/spec/index.md b/docs/spec/index.md index 149cc8f..a314fc0 100644 --- a/docs/spec/index.md +++ b/docs/spec/index.md @@ -3,33 +3,69 @@ sidebar_position: 3 --- # 🔌 Plugin Spec -| Property | Type | Description | -| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **[1]** | `string?` | Short plugin url. Will be expanded using `config.git.url_format` | -| **dir** | `string?` | A directory pointing to a local plugin | -| **url** | `string?` | A custom git url where the plugin is hosted | -| **name** | `string?` | A custom name for the plugin used for the local plugin directory and as the display name | -| **dev** | `boolean?` | When `true`, a local plugin directory will be used instead. See `config.dev` | -| **lazy** | `boolean?` | When `true`, the plugin will only be loaded when needed. Lazy-loaded plugins are automatically loaded when their Lua modules are `required`, or when one of the lazy-loading handlers triggers | -| **enabled** | `boolean?` or `fun():boolean` | When `false`, or if the `function` returns false, then this plugin will not be included in the spec | -| **cond** | `boolean?` or `fun(LazyPlugin):boolean` | When `false`, or if the `function` returns false, then this plugin will not be loaded. Useful to disable some plugins in vscode, or firenvim for example. | -| **dependencies** | `LazySpec[]` | A list of plugin names or plugin specs that should be loaded when the plugin loads. Dependencies are always lazy-loaded unless specified otherwise. When specifying a name, make sure the plugin spec has been defined somewhere else. | -| **init** | `fun(LazyPlugin)` | `init` functions are always executed during startup | -| **opts** | `table` or `fun(LazyPlugin, opts:table)` | `opts` should be a table (will be merged with parent specs), return a table (replaces parent specs) or should change a table. The table will be passed to the `Plugin.config()` function. Setting this value will imply `Plugin.config()` | -| **config** | `fun(LazyPlugin, opts:table)` or `true` | `config` is executed when the plugin loads. The default implementation will automatically run `require(MAIN).setup(opts)` if `opts` or `config = true` is set. Lazy uses several heuristics to determine the plugin's `MAIN` module automatically based on the plugin's **name**. See also `opts`. To use the default implementation without `opts` set `config` to `true`. | -| **main** | `string?` | You can specify the `main` module to use for `config()` and `opts()`, in case it can not be determined automatically. See `config()` | -| **build** | `fun(LazyPlugin)` or `string` or a list of build commands | `build` is executed when a plugin is installed or updated. Before running `build`, a plugin is first loaded. If it's a string it will be run as a shell command. When prefixed with `:` it is a Neovim command. You can also specify a list to executed multiple build commands. Some plugins provide their own `build.lua` which is automatically used by lazy. So no need to specify a build step for those plugins. | -| **branch** | `string?` | Branch of the repository | -| **tag** | `string?` | Tag of the repository | -| **commit** | `string?` | Commit of the repository | -| **version** | `string?` or `false` to override the default | Version to use from the repository. Full [Semver](https://devhints.io/semver) ranges are supported | -| **pin** | `boolean?` | When `true`, this plugin will not be included in updates | -| **submodules** | `boolean?` | When false, git submodules will not be fetched. Defaults to `true` | -| **event** | `string?` or `string[]` or `fun(self:LazyPlugin, event:string[]):string[]` or `{event:string[]\|string, pattern?:string[]\|string}` | Lazy-load on event. Events can be specified as `BufEnter` or with a pattern like `BufEnter *.lua` | -| **cmd** | `string?` or `string[]` or `fun(self:LazyPlugin, cmd:string[]):string[]` | Lazy-load on command | -| **ft** | `string?` or `string[]` or `fun(self:LazyPlugin, ft:string[]):string[]` | Lazy-load on filetype | -| **keys** | `string?` or `string[]` or `LazyKeysSpec[]` or `fun(self:LazyPlugin, keys:string[]):(string \| LazyKeysSpec)[]` | Lazy-load on key mapping | -| **module** | `false?` | Do not automatically load this Lua module when it's required somewhere | -| **priority** | `number?` | Only useful for **start** plugins (`lazy=false`) to force loading certain plugins first. Default priority is `50`. It's recommended to set this to a high number for colorschemes. | -| **optional** | `boolean?` | When a spec is tagged optional, it will only be included in the final spec, when the same plugin has been specified at least once somewhere else without `optional`. This is mainly useful for Neovim distros, to allow setting options on plugins that may/may not be part of the user's plugins | +## Source + +| Property | Type | Description | +| --------- | ---------- | -------------------------------------------------------------------------------------------------------------------- | +| **\[1\]** | `string?` | Short plugin url. Will be expanded using [`config.git.url_format`](../configuration/). Can also be a `url` or `dir`. | +| **dir** | `string?` | A directory pointing to a local plugin | +| **url** | `string?` | A custom git url where the plugin is hosted | +| **name** | `string?` | A custom name for the plugin used for the local plugin directory and as the display name | +| **dev** | `boolean?` | When `true`, a local plugin directory will be used instead. See [`config.dev`](../configuration/) | + +A valid spec should define one of `[1]`, `dir` or `url`. + +## Loading + +| Property | Type | Description | +| ---------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **dependencies** | `LazySpec[]` | A list of plugin names or plugin specs that should be loaded when the plugin loads. Dependencies are always lazy-loaded unless specified otherwise. When specifying a name, make sure the plugin spec has been defined somewhere else. | +| **enabled** | `boolean?` or `fun():boolean` | When `false`, or if the `function` returns false, then this plugin will not be included in the spec | +| **cond** | `boolean?` or `fun(LazyPlugin):boolean` | Behaves the same as `enabled`, but won't uninstall the plugin when the condition is `false`. Useful to disable some plugins in vscode, or firenvim for example. | +| **priority** | `number?` | Only useful for **start** plugins (`lazy=false`) to force loading certain plugins first. Default priority is `50`. It's recommended to set this to a high number for colorschemes. | + +## Setup + +| Property | Type | Description | +| ---------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **init** | `fun(LazyPlugin)` | `init` functions are always executed during startup | +| **opts** | `table` or `fun(LazyPlugin, opts:table)` | `opts` should be a table (will be merged with parent specs), return a table (replaces parent specs) or should change a table. The table will be passed to the `Plugin.config()` function. Setting this value will imply `Plugin.config()` | +| **config** | `fun(LazyPlugin, opts:table)` or `true` | `config` is executed when the plugin loads. The default implementation will automatically run `require(MAIN).setup(opts)` if `opts` or `config = true` is set. Lazy uses several heuristics to determine the plugin's `MAIN` module automatically based on the plugin's **name**. See also `opts`. To use the default implementation without `opts` set `config` to `true`. | +| **main** | `string?` | You can specify the `main` module to use for `config()` and `opts()`, in case it can not be determined automatically. See `config()` | +| **build** | `fun(LazyPlugin)` or `string` or a list of build commands | `build` is executed when a plugin is installed or updated. Before running `build`, a plugin is first loaded. If it's a string it will be run as a shell command. When prefixed with `:` it is a Neovim command. You can also specify a list to executed multiple build commands. Some plugins provide their own `build.lua` which is automatically used by lazy. So no need to specify a build step for those plugins. | +| **rocks** | `string[]?` | Add any [luarocks](https://luarocks.org/) dependencies. | + +## Lazy Loading + +| Property | Type | Description | +| --------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **lazy** | `boolean?` | When `true`, the plugin will only be loaded when needed. Lazy-loaded plugins are automatically loaded when their Lua modules are `required`, or when one of the lazy-loading handlers triggers | +| **event** | `string?` or `string[]` or `fun(self:LazyPlugin, event:string[]):string[]` or `{event:string[]\|string, pattern?:string[]\|string}` | Lazy-load on event. Events can be specified as `BufEnter` or with a pattern like `BufEnter *.lua` | +| **cmd** | `string?` or `string[]` or `fun(self:LazyPlugin, cmd:string[]):string[]` | Lazy-load on command | +| **ft** | `string?` or `string[]` or `fun(self:LazyPlugin, ft:string[]):string[]` | Lazy-load on filetype | +| **keys** | `string?` or `string[]` or `LazyKeysSpec[]` or `fun(self:LazyPlugin, keys:string[]):(string \| LazyKeysSpec)[]` | Lazy-load on [key mapping](/spec/lazy_loading#%EF%B8%8F-lazy-key-mappings) | + +Refer to the [Lazy Loading](./lazy_loading.md) section for more information. + +## Versioning + +| Property | Type | Description | +| -------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| **branch** | `string?` | Branch of the repository | +| **tag** | `string?` | Tag of the repository | +| **commit** | `string?` | Commit of the repository | +| **version** | `string?` or `false` to override the default | Version to use from the repository. Full [Semver](https://devhints.io/semver) ranges are supported | +| **pin** | `boolean?` | When `true`, this plugin will not be included in updates | +| **submodules** | `boolean?` | When false, git submodules will not be fetched. Defaults to `true` | + +Refer to the [Versioning](./versioning.md) section for more information. + +## Advanced + +| Property | Type | Description | +| ------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **optional** | `boolean?` | When a spec is tagged optional, it will only be included in the final spec, when the same plugin has been specified at least once somewhere else without `optional`. This is mainly useful for Neovim distros, to allow setting options on plugins that may/may not be part of the user's plugins. | +| **specs** | `LazySpec` | A list of plugin specs defined in the scope of the plugin. This is mainly useful for Neovim distros, to allow setting options on plugins that may/may not be part of the user's plugins. When the plugin is disabled, none of the scoped specs will be included in the final spec. Similar to `dependencies` without the automatic loading of the specs. | +| **module** | `false?` | Do not automatically load this Lua module when it's required somewhere | +| **import** | `string?` | Import the given spec module. | diff --git a/docs/spec/lazy_loading.md b/docs/spec/lazy_loading.md index 1b7d5b2..4ee68f0 100644 --- a/docs/spec/lazy_loading.md +++ b/docs/spec/lazy_loading.md @@ -1,14 +1,16 @@ # Lazy Loading -**lazy.nvim** automagically lazy-loads Lua modules, so it is not needed to -specify `module=...` everywhere in your plugin specification. This means that if +**lazy.nvim** automagically lazy-loads Lua modules. This means that if you have a plugin `A` that is lazy-loaded and a plugin `B` that requires a module of plugin `A`, then plugin `A` will be loaded on demand as expected. -If you don't want this behavior for a certain plugin, you can specify that with `module=false`. -You can then manually load the plugin with `:Lazy load foobar.nvim`. +:::tip You can configure **lazy.nvim** to lazy-load all plugins by default with `config.defaults.lazy = true`. +Make sure you've configured lazy-loading, for your plugins to avoid unexpected behavior. +Only do this if you know what you are doing, as it can lead to unexpected behavior. + +::: Additionally, you can also lazy-load on **events**, **commands**, **file types** and **key mappings**. @@ -24,9 +26,13 @@ Plugins will be lazy-loaded when one of the following is `true`: Colorscheme plugins can be configured with `lazy=true`. The plugin will automagically load when doing `colorscheme foobar`. -> **NOTE:** since **start** plugins can possibly change existing highlight groups, -> it's important to make sure that your main **colorscheme** is loaded first. -> To ensure this you can use the `priority=1000` field. **_(see the examples)_** +:::warning + +since **start** plugins can possibly change existing highlight groups, +it's important to make sure that your main **colorscheme** is loaded first. +To ensure this you can use the `priority=1000` field. **_(see the [examples](./examples.md))_** + +::: ## ⌨ī¸ Lazy Key Mappings diff --git a/docs/usage/index.md b/docs/usage/index.md index 9f6007a..144be25 100644 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -3,6 +3,23 @@ sidebar_position: 6 --- # 🚀 Usage +## â–ļī¸ Startup Sequence + +**lazy.nvim** does **NOT** use Neovim packages and even disables plugin loading +completely (`vim.go.loadplugins = false`). It takes over the complete +startup sequence for more flexibility and better performance. + +In practice this means that step 10 of [Neovim Initialization](https://neovim.io/doc/user/starting.html#initialization) is done by Lazy: + +1. All the plugins' `init()` functions are executed +2. All plugins with `lazy=false` are loaded. This includes sourcing `/plugin` and `/ftdetect` files. (`/after` will not be sourced yet) +3. All files from `/plugin` and `/ftdetect` directories in your rtp are sourced (excluding `/after`) +4. All `/after/plugin` files are sourced (this includes `/after` from plugins) + +Files from runtime directories are always sourced in alphabetical order. + +## 🚀 Commands + Plugins are managed with the `:Lazy` command. Open the help with `` to see all the key mappings. @@ -17,24 +34,24 @@ Any operation can be started from the UI, with a sub command or an API function: -| Command | Lua | Description | -| --- | --- | --- | -| `:Lazy build {plugins}` | `require("lazy").build(opts)` | Rebuild a plugin | -| `:Lazy check [plugins]` | `require("lazy").check(opts?)` | Check for updates and show the log (git fetch) | -| `:Lazy clean [plugins]` | `require("lazy").clean(opts?)` | Clean plugins that are no longer needed | -| `:Lazy clear` | `require("lazy").clear()` | Clear finished tasks | -| `:Lazy debug` | `require("lazy").debug()` | Show debug information | -| `:Lazy health` | `require("lazy").health()` | Run `:checkhealth lazy` | -| `:Lazy help` | `require("lazy").help()` | Toggle this help page | -| `:Lazy home` | `require("lazy").home()` | Go back to plugin list | -| `:Lazy install [plugins]` | `require("lazy").install(opts?)` | Install missing plugins | -| `:Lazy load {plugins}` | `require("lazy").load(opts)` | Load a plugin that has not been loaded yet. Similar to `:packadd`. Like `:Lazy load foo.nvim`. Use `:Lazy! load` to skip `cond` checks. | -| `:Lazy log [plugins]` | `require("lazy").log(opts?)` | Show recent updates | -| `:Lazy profile` | `require("lazy").profile()` | Show detailed profiling | -| `:Lazy reload {plugins}` | `require("lazy").reload(opts)` | Reload a plugin (experimental!!) | +| Command | Lua | Description | +| ------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `:Lazy build {plugins}` | `require("lazy").build(opts)` | Rebuild a plugin | +| `:Lazy check [plugins]` | `require("lazy").check(opts?)` | Check for updates and show the log (git fetch) | +| `:Lazy clean [plugins]` | `require("lazy").clean(opts?)` | Clean plugins that are no longer needed | +| `:Lazy clear` | `require("lazy").clear()` | Clear finished tasks | +| `:Lazy debug` | `require("lazy").debug()` | Show debug information | +| `:Lazy health` | `require("lazy").health()` | Run `:checkhealth lazy` | +| `:Lazy help` | `require("lazy").help()` | Toggle this help page | +| `:Lazy home` | `require("lazy").home()` | Go back to plugin list | +| `:Lazy install [plugins]` | `require("lazy").install(opts?)` | Install missing plugins | +| `:Lazy load {plugins}` | `require("lazy").load(opts)` | Load a plugin that has not been loaded yet. Similar to `:packadd`. Like `:Lazy load foo.nvim`. Use `:Lazy! load` to skip `cond` checks. | +| `:Lazy log [plugins]` | `require("lazy").log(opts?)` | Show recent updates | +| `:Lazy profile` | `require("lazy").profile()` | Show detailed profiling | +| `:Lazy reload {plugins}` | `require("lazy").reload(opts)` | Reload a plugin (experimental!!) | | `:Lazy restore [plugins]` | `require("lazy").restore(opts?)` | Updates all plugins to the state in the lockfile. For a single plugin: restore it to the state in the lockfile or to a given commit under the cursor | -| `:Lazy sync [plugins]` | `require("lazy").sync(opts?)` | Run install, clean and update | -| `:Lazy update [plugins]` | `require("lazy").update(opts?)` | Update plugins. This will also update the lockfile | +| `:Lazy sync [plugins]` | `require("lazy").sync(opts?)` | Run install, clean and update | +| `:Lazy update [plugins]` | `require("lazy").update(opts?)` | Update plugins. This will also update the lockfile | @@ -96,7 +113,7 @@ require("lualine").setup({ -### 📆 User Events +## 📆 User Events The following user events will be triggered: @@ -119,94 +136,6 @@ The following user events will be triggered: - **LazyVimStarted**: triggered after `UIEnter` when `require("lazy").stats().startuptime` has been calculated. Useful to update the startuptime on your dashboard. -## 🐛 Debug - -See an overview of active lazy-loading handlers and what's in the module cache. - -![image](https://user-images.githubusercontent.com/292349/208301790-7eedbfa5-d202-4e70-852e-de68aa47233b.png) - -## â–ļī¸ Startup Sequence - -**lazy.nvim** does **NOT** use Neovim packages and even disables plugin loading -completely (`vim.go.loadplugins = false`). It takes over the complete -startup sequence for more flexibility and better performance. - -In practice this means that step 10 of [Neovim Initialization](https://neovim.io/doc/user/starting.html#initialization) is done by Lazy: - -1. All the plugins' `init()` functions are executed -2. All plugins with `lazy=false` are loaded. This includes sourcing `/plugin` and `/ftdetect` files. (`/after` will not be sourced yet) -3. All files from `/plugin` and `/ftdetect` directories in your rtp are sourced (excluding `/after`) -4. All `/after/plugin` files are sourced (this includes `/after` from plugins) - -Files from runtime directories are always sourced in alphabetical order. - -## 📂 Structuring Your Plugins - -Some users may want to split their plugin specs in multiple files. -Instead of passing a spec table to `setup()`, you can use a Lua module. -The specs from the **module** and any top-level **sub-modules** will be merged together in the final spec, -so it is not needed to add `require` calls in your main plugin file to the other files. - -The benefits of using this approach: - -- Simple to **add** new plugin specs. Just create a new file in your plugins module. -- Allows for **caching** of all your plugin specs. This becomes important if you have a lot of smaller plugin specs. -- Spec changes will automatically be **reloaded** when they're updated, so the `:Lazy` UI is always up to date. - -Example: - -- `~/.config/nvim/init.lua` - -```lua -require("lazy").setup("plugins") -``` - -- `~/.config/nvim/lua/plugins.lua` or `~/.config/nvim/lua/plugins/init.lua` **_(this file is optional)_** - -```lua -return { - "folke/neodev.nvim", - "folke/which-key.nvim", - { "folke/neoconf.nvim", cmd = "Neoconf" }, -} -``` - -- Any lua file in `~/.config/nvim/lua/plugins/*.lua` will be automatically merged in the main plugin spec - -For a real-life example, you can check [LazyVim](https://github.com/LazyVim/LazyVim) and more specifically: - -- [lazyvim.plugins](https://github.com/LazyVim/LazyVim/tree/main/lua/lazyvim/plugins) contains all the plugin specs that will be loaded - -### ↩ī¸ Importing Specs, `config` & `opts` - -As part of a spec, you can add `import` statements to import additional plugin modules. -Both of the `setup()` calls are equivalent: - -```lua -require("lazy").setup("plugins") - --- Same as: -require("lazy").setup({{import = "plugins"}}) -``` - -To import multiple modules from a plugin, add additional specs for each import. -For example, to import LazyVim core plugins and an optional plugin: - -```lua -require("lazy").setup({ - spec = { - { "LazyVim/LazyVim", import = "lazyvim.plugins" }, - { import = "lazyvim.plugins.extras.coding.copilot" }, - } -}) -``` - -When you import specs, you can override them by simply adding a spec for the same plugin to your local -specs, adding any keys you want to override / merge. - -`opts`, `dependencies`, `cmd`, `event`, `ft` and `keys` are always merged with the parent spec. -Any other property will override the property from the parent spec. - ## ❌ Uninstalling To uninstall **lazy.nvim**, you need to remove the following files and directories: diff --git a/docs/usage/lockfile.md b/docs/usage/lockfile.md index 995ae60..ceb0213 100644 --- a/docs/usage/lockfile.md +++ b/docs/usage/lockfile.md @@ -1,6 +1,6 @@ -# 🔒 Lockfile `lazy-lock.json` +# 🔒 Lockfile -After every **update**, the local lockfile is updated with the installed revisions. +After every **update**, the local lockfile (`lazy-lock.json`) is updated with the installed revisions. It is recommended to have this file under version control. If you use your Neovim config on multiple machines, using the lockfile, you can diff --git a/docs/usage/profiling.md b/docs/usage/profiling.md index ec7e740..63de8b8 100644 --- a/docs/usage/profiling.md +++ b/docs/usage/profiling.md @@ -1,4 +1,4 @@ -# ⚡ Profiling +# ⚡ Profiling & Debug Great care has been taken to make the startup code (`lazy.core`) as efficient as possible. During startup, all Lua files used before `VimEnter` or `BufReadPre` are byte-compiled and cached, @@ -10,3 +10,9 @@ My config for example loads in about `11ms` with `93` plugins. I do a lot of laz The profiling view shows you why and how long it took to load your plugins. ![image](https://user-images.githubusercontent.com/292349/208301766-5c400561-83c3-4811-9667-1ec4bb3c43b8.png) + +## 🐛 Debug + +See an overview of active lazy-loading handlers and what's in the module cache. + +![image](https://user-images.githubusercontent.com/292349/208301790-7eedbfa5-d202-4e70-852e-de68aa47233b.png) diff --git a/docs/usage/structuring.md b/docs/usage/structuring.md new file mode 100644 index 0000000..8266a12 --- /dev/null +++ b/docs/usage/structuring.md @@ -0,0 +1,66 @@ +# 📂 Structuring Your Plugins + +Some users may want to split their plugin specs in multiple files. +Instead of passing a spec table to `setup()`, you can use a Lua module. +The specs from the **module** and any top-level **sub-modules** will be merged together in the final spec, +so it is not needed to add `require` calls in your main plugin file to the other files. + +The benefits of using this approach: + +- Simple to **add** new plugin specs. Just create a new file in your plugins module. +- Allows for **caching** of all your plugin specs. This becomes important if you have a lot of smaller plugin specs. +- Spec changes will automatically be **reloaded** when they're updated, so the `:Lazy` UI is always up to date. + +Example: + +- `~/.config/nvim/init.lua` + +```lua +require("lazy").setup("plugins") +``` + +- `~/.config/nvim/lua/plugins.lua` or `~/.config/nvim/lua/plugins/init.lua` **_(this file is optional)_** + +```lua +return { + "folke/neodev.nvim", + "folke/which-key.nvim", + { "folke/neoconf.nvim", cmd = "Neoconf" }, +} +``` + +- Any lua file in `~/.config/nvim/lua/plugins/*.lua` will be automatically merged in the main plugin spec + +For a real-life example, you can check [LazyVim](https://github.com/LazyVim/LazyVim) and more specifically: + +- [lazyvim.plugins](https://github.com/LazyVim/LazyVim/tree/main/lua/lazyvim/plugins) contains all the plugin specs that will be loaded + +### ↩ī¸ Importing Specs, `config` & `opts` + +As part of a spec, you can add `import` statements to import additional plugin modules. +Both of the `setup()` calls are equivalent: + +```lua +require("lazy").setup("plugins") + +-- Same as: +require("lazy").setup({{import = "plugins"}}) +``` + +To import multiple modules from a plugin, add additional specs for each import. +For example, to import LazyVim core plugins and an optional plugin: + +```lua +require("lazy").setup({ + spec = { + { "LazyVim/LazyVim", import = "lazyvim.plugins" }, + { import = "lazyvim.plugins.extras.coding.copilot" }, + } +}) +``` + +When you import specs, you can override them by simply adding a spec for the same plugin to your local +specs, adding any keys you want to override / merge. + +`opts`, `dependencies`, `cmd`, `event`, `ft` and `keys` are always merged with the parent spec. +Any other property will override the property from the parent spec. diff --git a/lua/build.lua b/lua/build.lua index 62cc9ce..22d63b1 100644 --- a/lua/build.lua +++ b/lua/build.lua @@ -5,63 +5,88 @@ local M = {} ---@param path string local function dir(path) - local plugin, extra = path:match("([^/]+)(.*)") - return require("lazy.core.config").plugins[plugin].dir .. extra + local plugin, extra = path:match("([^/]+)(.*)") + return require("lazy.core.config").plugins[plugin].dir .. extra end M.extract = { - installation = { - bootstrap = { - lang = 'lua title="lua/config/lazy.lua"', - content = Docs.extract(dir("lazy.nvim/lua/lazy/init.lua"), "function M%.bootstrap%(%)\n(.-)\nend"), - }, - }, - ["configuration/index"] = { - config = Docs.extract(dir("lazy.nvim/lua/lazy/core/config.lua"), "\nM%.defaults = ({.-\n})") - :gsub("%s*debug = false.\n", "\n"), - }, - ["configuration/highlights"] = { - colors = Docs.colors({ - path = dir("lazy.nvim/lua/lazy/view/colors.lua"), - }), - }, - ["spec/examples"] = { - examples = Util.read_file(dir("lazy.nvim/lua/lazy/example.lua")), - }, - ["usage/index"] = { - stats = Docs.extract(dir("lazy.nvim/lua/lazy/stats.lua"), "\nM%._stats = ({.-\n})"), - commands = Docs.commands(), - }, + ["configuration/index"] = { + config = Docs.extract(dir("lazy.nvim/lua/lazy/core/config.lua"), "\nM%.defaults = ({.-\n})") + :gsub("%s*debug = false.\n", "\n"), + }, + ["configuration/highlights"] = { + colors = Docs.colors({ + path = dir("lazy.nvim/lua/lazy/view/colors.lua"), + }), + }, + ["spec/examples"] = { + examples = Util.read_file(dir("lazy.nvim/lua/lazy/example.lua")), + }, + ["usage/index"] = { + stats = Docs.extract(dir("lazy.nvim/lua/lazy/stats.lua"), "\nM%._stats = ({.-\n})"), + commands = Docs.commands(), + }, } local function exec(cmd) - return vim.system(vim.split(cmd, " "), { text = true }):wait() + return vim.system(vim.split(cmd, " "), { text = true }):wait() end function M.themes() - exec("rm -rf src/themes") - exec("mkdir -p src/themes") - exec("cp -r .nvim/plugins/tokyonight.nvim/extras/prism src/themes/prism") + exec("rm -rf src/themes") + exec("mkdir -p src/themes") + exec("cp -r .nvim/plugins/tokyonight.nvim/extras/prism src/themes/prism") +end + +function M.installation() + local install = Util.read_file("lua/tpl/install.lua") + local install_multi = install:gsub( + "spec = {}", + [[spec = { + -- import your plugins + { import = "plugins" }, + }]] + ) + local install_single = install:gsub( + "spec = {}", + [[spec = { + -- add your plugins here + }]] + ) + return { + install_single = { + content = install_single, + lang = 'lua title="~/.config/nvim/init.lua"', + }, + install_multi = { + content = install_multi, + lang = 'lua title="~/.config/nvim/lua/config/lazy.lua"', + }, + } end function M.docs() - for name, data in pairs(M.extract) do - local md = "docs/" .. name .. ".md" - print("Building " .. md) - Docs.save(data, md) - end + M.extract.installation = M.installation() + for name, data in pairs(M.extract) do + local md = "docs/" .. name .. ".md" + if vim.uv.fs_stat(md .. "x") then + md = md .. "x" + end + print("Building " .. md) + Docs.save(data, md) + end end function M._old() - M.save({ - stats = M.extract("lua/lazy/stats.lua", "\nM%._stats = ({.-\n})"), - commands = M.commands(), - }) + M.save({ + stats = M.extract("lua/lazy/stats.lua", "\nM%._stats = ({.-\n})"), + commands = M.commands(), + }) end function M.update() - M.themes() - M.docs() + M.themes() + M.docs() end return M diff --git a/lua/init.lua b/lua/init.lua index 04dc3f2..8194440 100644 --- a/lua/init.lua +++ b/lua/init.lua @@ -3,54 +3,54 @@ local root = vim.fn.fnamemodify("./.nvim", ":p") -- set stdpaths to use .repro for _, name in ipairs({ "config", "data", "state", "cache" }) do - vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name + vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name end local lazy_dev = vim.fn.expand("~/projects/lazy.nvim") if vim.uv.fs_stat(lazy_dev) then - vim.opt.runtimepath:prepend(lazy_dev) + vim.opt.runtimepath:prepend(lazy_dev) else - -- bootstrap lazy - local lazypath = root .. "/plugins/lazy.nvim" - if not vim.loop.fs_stat(lazypath) then - print("Bootstrapping lazy.nvim") - vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath }) - end - vim.opt.runtimepath:prepend(lazypath) + -- bootstrap lazy + local lazypath = root .. "/plugins/lazy.nvim" + if not vim.loop.fs_stat(lazypath) then + print("Bootstrapping lazy.nvim") + vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath }) + end + vim.opt.runtimepath:prepend(lazypath) end local function main() - print("Installing plugins") - require("lazy").setup({ - spec = { - "folke/tokyonight.nvim", - }, - root = root .. "/plugins", - }) + print("Installing plugins") + require("lazy").setup({ + spec = { + "folke/tokyonight.nvim", + }, + root = root .. "/plugins", + }) - if vim.o.filetype == "lazy" then - vim.cmd.close() - end + if vim.o.filetype == "lazy" then + vim.cmd.close() + end - print("Updating plugins") - -- update plugins, wait for it to finish and don't show the output - require("lazy").update({ wait = true, show = false }) - -- require("lazy.core.cache").reset() + print("Updating plugins") + -- update plugins, wait for it to finish and don't show the output + require("lazy").update({ wait = true, show = false }) + -- require("lazy.core.cache").reset() - vim.opt.rtp:append(".") + vim.opt.rtp:append(".") - print("Building docs") + print("Building docs") - require("build").update() + require("build").update() - print("Done!\n") + print("Done!\n") end local Util = require("lazy.core.util") Util.try(main, { - on_error = function(err) - print(err) - os.exit(1) - end, + on_error = function(err) + print(err) + os.exit(1) + end, }) os.exit(0) diff --git a/lua/tpl/install.lua b/lua/tpl/install.lua new file mode 100644 index 0000000..9954180 --- /dev/null +++ b/lua/tpl/install.lua @@ -0,0 +1,46 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` before loading lazy.nvim +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = " " -- Make sure to set `mapleader` before lazy so your mappings are correct +vim.g.maplocalleader = "\\" -- Same for `maplocalleader` + +-- Setup lazy.nvim +require("lazy").setup({ + -- highlight-start + spec = {}, + -- highlight-end + defaults = { + -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. + -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. + lazy = false, + -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, + -- have outdated releases, which may break your Neovim install. + version = false, -- always use the latest git commit + -- version = "*", -- try installing the latest stable version for plugins that support semver + }, + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + checker = { enabled = true }, -- automatically check for plugin updates + performance = { + rtp = { + -- uncomment the below to disable some rtp plugins + disabled_plugins = { + -- "gzip", + -- "matchit", + -- "matchparen", + -- "netrwPlugin", + -- "tarPlugin", + -- "tohtml", + -- "tutor", + -- "zipPlugin", + }, + }, + }, +}) diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..9732fe6 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,6 @@ +indent_type = "Spaces" +indent_width = 2 +column_width = 120 +[sort_requires] +enabled = true +