Compare commits

..

No commits in common. "main" and "v11.7.0" have entirely different histories.

63 changed files with 577 additions and 3606 deletions

View File

@ -1,7 +0,0 @@
root = true
[*]
insert_final_newline = true
indent_style = space
indent_size = 2
charset = utf-8

View File

@ -1,3 +1,3 @@
{ {
".": "11.17.5" ".": "11.7.0"
} }

View File

@ -6,10 +6,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
**Before** reporting an issue, make sure to read the [documentation](https://github.com/folke/lazy.nvim) **Before** reporting an issue, make sure to read the [documentation](https://github.com/folke/lazy.nvim) and search [existing issues](https://github.com/folke/lazy.nvim/issues). Usage questions such as ***"How do I...?"*** belong in [Discussions](https://github.com/folke/lazy.nvim/discussions) and will be closed.
and search [existing issues](https://github.com/folke/lazy.nvim/issues).
Usage questions such as ***"How do I...?"*** belong in [Discussions](https://github.com/folke/lazy.nvim/discussions) and will be closed.
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Did you check docs and existing issues? label: Did you check docs and existing issues?
@ -17,8 +14,6 @@ body:
options: options:
- label: I have read all the lazy.nvim docs - label: I have read all the lazy.nvim docs
required: true required: true
- label: I have updated the plugin to the latest version before submitting this issue
required: true
- label: I have searched the existing issues of lazy.nvim - label: I have searched the existing issues of lazy.nvim
required: true required: true
- label: I have searched the existing issues of plugins related to this issue - label: I have searched the existing issues of plugins related to this issue
@ -62,14 +57,32 @@ body:
label: Repro label: Repro
description: Minimal `init.lua` to reproduce this issue. Save as `repro.lua` and run with `nvim -u repro.lua` description: Minimal `init.lua` to reproduce this issue. Save as `repro.lua` and run with `nvim -u repro.lua`
value: | value: |
vim.env.LAZY_STDPATH = ".repro" -- DO NOT change the paths and don't remove the colorscheme
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))() local root = vim.fn.fnamemodify("./.repro", ":p")
require("lazy.minit").repro({ -- set stdpaths to use .repro
spec = { for _, name in ipairs({ "config", "data", "state", "cache" }) do
-- add any other plugins here vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
}, end
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)
-- install plugins
local plugins = {
"folke/tokyonight.nvim",
-- add any other plugins here
}
require("lazy").setup(plugins, {
root = root .. "/plugins",
}) })
render: lua
vim.cmd.colorscheme("tokyonight")
-- add anything else here
render: Lua
validations: validations:
required: false required: false

View File

@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Ask a question
url: https://github.com/folke/lazy.nvim/discussions
about: Use Github discussions instead

View File

@ -1,16 +0,0 @@
## Description
<!-- Describe the big picture of your changes to communicate to the maintainers
why we should accept this pull request. -->
## Related Issue(s)
<!--
If this PR fixes any issues, please link to the issue here.
- Fixes #<issue_number>
-->
## Screenshots
<!-- Add screenshots of the changes if applicable. -->

View File

@ -1,6 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2 version: 2
updates: updates:
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" directory: "/" # Location of package manifests
schedule: schedule:
interval: "weekly" interval: "weekly"

View File

@ -1,15 +1,81 @@
name: CI name: CI
on: on:
push: push:
branches: [main, master]
pull_request: pull_request:
jobs: jobs:
ci: tests:
uses: folke/github/.github/workflows/ci.yml@main strategy:
secrets: inherit matrix:
with: # os: [ubuntu-latest, windows-latest]
plugin: lazy.nvim os: [ubuntu-latest]
repo: folke/lazy.nvim runs-on: ${{ matrix.os }}
docs: false steps:
- uses: actions/checkout@v4
- name: Install Neovim
shell: bash
run: |
mkdir -p /tmp/nvim
wget -q https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -O /tmp/nvim/nvim.appimage
cd /tmp/nvim
chmod a+x ./nvim.appimage
./nvim.appimage --appimage-extract
echo "/tmp/nvim/squashfs-root/usr/bin/" >> $GITHUB_PATH
- name: Run Tests
run: |
nvim --version
[ ! -d tests ] && exit 0
./tests/run
community:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Neovim
shell: bash
run: |
mkdir -p /tmp/nvim
wget -q https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -O /tmp/nvim/nvim.appimage
cd /tmp/nvim
chmod a+x ./nvim.appimage
./nvim.appimage --appimage-extract
echo "/tmp/nvim/squashfs-root/usr/bin/" >> $GITHUB_PATH
- name: Rockspec Build
id: rockspec-build
uses: actions/cache@v4
with:
path: build
key: rockspec-build
- name: Generate Rockspec
if: steps.rockspec-build.cache-hit != 'true'
run: |
nvim -l lua/lazy/build.lua
- name: Push changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "chore(build): auto-generate rockspec mappings"
commit_user_name: "github-actions[bot]"
commit_user_email: "github-actions[bot]@users.noreply.github.com"
commit_author: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
release:
name: release
if: ${{ github.ref == 'refs/heads/main' }}
needs:
- tests
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
config-file: .github/release-please-config.json
manifest-file: .github/.release-please-manifest.json
- uses: actions/checkout@v4
- name: tag stable versions
if: ${{ steps.release.outputs.release_created }}
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git remote add gh-token "https://${{ secrets.GITHUB_TOKEN }}@github.com/google-github-actions/release-please-action.git"
git tag -d stable || true
git push origin :stable || true
git tag -a stable -m "Last Stable Release"
git push origin stable

View File

@ -1,30 +0,0 @@
name: Community
on:
push:
branches:
- main
jobs:
community:
runs-on: ubuntu-latest
if: ${{ github.ref == 'refs/heads/main' && github.repository_owner == 'folke' }}
steps:
- uses: actions/checkout@v6
- uses: folke/github/neovim@main
- name: Rockspec Build
id: rockspec-build
uses: actions/cache@v5
with:
path: build
key: rockspec-build
- name: Generate Rockspec
if: steps.rockspec-build.cache-hit != 'true'
run: |
nvim -l lua/lazy/build.lua
- name: Push changes
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore(build): auto-generate rockspec mappings"
commit_user_name: "github-actions[bot]"
commit_user_email: "github-actions[bot]@users.noreply.github.com"
commit_author: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"

View File

@ -1,19 +0,0 @@
name: Docs
on:
push:
branches:
- main
jobs:
docs:
runs-on: ubuntu-latest
if: ${{ github.ref == 'refs/heads/main' && github.repository_owner == 'folke' }}
env:
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v6
with:
ref: docs
- name: Generate Docs
shell: bash
run: gh workflow run "Deploy to Github Pages" --ref docs

View File

@ -1,8 +0,0 @@
name: "PR Labeler"
on:
- pull_request_target
jobs:
labeler:
uses: folke/github/.github/workflows/labeler.yml@main
secrets: inherit

View File

@ -1,18 +0,0 @@
name: PR Title
on:
pull_request_target:
types:
- opened
- edited
- synchronize
- reopened
- ready_for_review
permissions:
pull-requests: read
jobs:
pr-title:
uses: folke/github/.github/workflows/pr.yml@main
secrets: inherit

View File

@ -1,11 +0,0 @@
name: Stale Issues & PRs
on:
schedule:
- cron: "30 1 * * *"
jobs:
stale:
if: contains(fromJSON('["folke", "LazyVim"]'), github.repository_owner)
uses: folke/github/.github/workflows/stale.yml@main
secrets: inherit

View File

@ -1,13 +0,0 @@
name: Update Repo
on:
workflow_dispatch:
schedule:
# Run every hour
- cron: "0 * * * *"
jobs:
update:
if: contains(fromJSON('["folke", "LazyVim"]'), github.repository_owner)
uses: folke/github/.github/workflows/update.yml@main
secrets: inherit

16
.gitignore vendored
View File

@ -1,9 +1,9 @@
*.log
/.repro
/.tests
/build
/debug
/doc/tags
foo.*
node_modules
tt.* tt.*
.tests
doc/tags
debug
.repro
foo.*
*.log
data
build

View File

@ -1,3 +0,0 @@
config:
MD013: false
MD033: false

View File

@ -1 +0,0 @@
lua/lazy/community/_generated.lua

View File

@ -1,297 +1,5 @@
# Changelog # Changelog
## [11.17.5](https://github.com/folke/lazy.nvim/compare/v11.17.4...v11.17.5) (2025-11-06)
### Bug Fixes
* **luarocks:** proper parsing of dependency name. Closes [#2086](https://github.com/folke/lazy.nvim/issues/2086) ([5c09e6f](https://github.com/folke/lazy.nvim/commit/5c09e6fe71f4bb930eeffe24d45762fa3ffada4e))
## [11.17.4](https://github.com/folke/lazy.nvim/compare/v11.17.3...v11.17.4) (2025-11-04)
### Bug Fixes
* **plugin:** proper error message when a plugin spec returns more than one value. ([dfdc85e](https://github.com/folke/lazy.nvim/commit/dfdc85e18930a3f1643e83c8ed0c514ca85e49fa))
## [11.17.3](https://github.com/folke/lazy.nvim/compare/v11.17.2...v11.17.3) (2025-10-28)
### Bug Fixes
* **luarocks:** update to lumen-oss for binaries. Closes [#2060](https://github.com/folke/lazy.nvim/issues/2060). Closes [#2059](https://github.com/folke/lazy.nvim/issues/2059) ([e31789c](https://github.com/folke/lazy.nvim/commit/e31789c675e2f591a20fc894b6713398eaa5dddd))
## [11.17.2](https://github.com/folke/lazy.nvim/compare/v11.17.1...v11.17.2) (2025-10-23)
### Bug Fixes
* **luarocks:** add plugin to lua path if it was already loaded before we know its a luarock ([147f5a3](https://github.com/folke/lazy.nvim/commit/147f5a3f55b5491bbc77a55ce846ef5eb575fa42))
* **plugin:** check that path is actually in root dir. Closes [#2075](https://github.com/folke/lazy.nvim/issues/2075) ([16e5271](https://github.com/folke/lazy.nvim/commit/16e52715b70b4d0fc6af3563ccc0ed9df82ae23e))
* **stats:** better support for different `time_t` sizes. See [#2049](https://github.com/folke/lazy.nvim/issues/2049) ([1ea3c40](https://github.com/folke/lazy.nvim/commit/1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1))
## [11.17.1](https://github.com/folke/lazy.nvim/compare/v11.17.0...v11.17.1) (2025-02-25)
### Bug Fixes
* **bootstrap:** support for older Neovim versions ([1c9ba37](https://github.com/folke/lazy.nvim/commit/1c9ba3704564a2e34a22191bb89678680ffeb245))
* **meta:** rebuild dirty right after disable. See [#1889](https://github.com/folke/lazy.nvim/issues/1889) ([d51cf69](https://github.com/folke/lazy.nvim/commit/d51cf6978321d659e68a8bc38ee806bd2517a196))
## [11.17.0](https://github.com/folke/lazy.nvim/compare/v11.16.2...v11.17.0) (2025-02-24)
### Features
* **config,render:** allow customizing the debug icon ([#1863](https://github.com/folke/lazy.nvim/issues/1863)) ([a9c660d](https://github.com/folke/lazy.nvim/commit/a9c660d6ef1b396869d3d951760aa7a3dbfe575f))
* **util:** pass lang to `vim.notify` so that snacks notifier can render the ft. Closes [#1919](https://github.com/folke/lazy.nvim/issues/1919) ([c6a57a3](https://github.com/folke/lazy.nvim/commit/c6a57a3534d3494bcc5ff9b0586e141bdb0280eb))
### Bug Fixes
* **config:** add missing space on the default debug icon ([#1879](https://github.com/folke/lazy.nvim/issues/1879)) ([4df5c4d](https://github.com/folke/lazy.nvim/commit/4df5c4d65a3bbf801edd9ec55fb1ae55cfa72dd0))
* **meta:** disable top-level specs before the rest. Closes [#1889](https://github.com/folke/lazy.nvim/issues/1889) ([f81a3fb](https://github.com/folke/lazy.nvim/commit/f81a3fb7feaf460ec7c8c983682b4a693b18fdd4))
* **ui:** do not show virt_lines for messages ([#1904](https://github.com/folke/lazy.nvim/issues/1904)) ([f15a939](https://github.com/folke/lazy.nvim/commit/f15a93907ddad3d9139aea465ae18336d87f5ce6))
## [11.16.2](https://github.com/folke/lazy.nvim/compare/v11.16.1...v11.16.2) (2024-12-13)
### Bug Fixes
* **meta:** when a plugin is both optional and disabled, then just delete it from the list ([805b85c](https://github.com/folke/lazy.nvim/commit/805b85c2ea3bd6f9506ef22cbd6e3a39172b5b08))
## [11.16.1](https://github.com/folke/lazy.nvim/compare/v11.16.0...v11.16.1) (2024-12-09)
### Bug Fixes
* **types:** ensure all fields for `LazyPluginSpec` are optional ([#1843](https://github.com/folke/lazy.nvim/issues/1843)) ([703be1d](https://github.com/folke/lazy.nvim/commit/703be1dda35e142e76e94e7503cf67d6b98a1d35)), closes [#1842](https://github.com/folke/lazy.nvim/issues/1842)
## [11.16.0](https://github.com/folke/lazy.nvim/compare/v11.15.0...v11.16.0) (2024-12-07)
### Features
* **plugin:** added support for virtual plugins. Closes [#1836](https://github.com/folke/lazy.nvim/issues/1836) ([ee64abc](https://github.com/folke/lazy.nvim/commit/ee64abc76be2b237b95d241a924b0323005b868a))
### Bug Fixes
* **plugin:** don't check if dir exists for virtual plugins ([656cf43](https://github.com/folke/lazy.nvim/commit/656cf4309396b7b8b62984e923bf8d8a0013f7d7))
* **render:** show correct key for home. Fixes [#1796](https://github.com/folke/lazy.nvim/issues/1796) ([b08dba8](https://github.com/folke/lazy.nvim/commit/b08dba8107b5bdaaa007f18cf6c0cc0e0fd576aa))
## [11.15.0](https://github.com/folke/lazy.nvim/compare/v11.14.2...v11.15.0) (2024-12-05)
### Features
* **plugin:** show error for local plugins that don't exist. Fixes [#1773](https://github.com/folke/lazy.nvim/issues/1773) ([9570a5a](https://github.com/folke/lazy.nvim/commit/9570a5ae7b17dcde4718c7458fd986c10f015a99))
## [11.14.2](https://github.com/folke/lazy.nvim/compare/v11.14.1...v11.14.2) (2024-11-10)
### Bug Fixes
* **bootstrap:** single forward slash. Fixes [#1747](https://github.com/folke/lazy.nvim/issues/1747) ([aca30f6](https://github.com/folke/lazy.nvim/commit/aca30f63619a7492ecdea8833a065cf83c80f764))
* **completion:** check if command string is a prefix of Lazy ([#1760](https://github.com/folke/lazy.nvim/issues/1760)) ([e9fd76e](https://github.com/folke/lazy.nvim/commit/e9fd76e239cc18da289f9a3f80f35fa16b003175)), closes [#1758](https://github.com/folke/lazy.nvim/issues/1758)
* **docs:** always update helptags for local plugins ([60cf258](https://github.com/folke/lazy.nvim/commit/60cf258a9ae7fffe04bb31141141a91845158dcc))
* **luarocks:** try to install from root manifest ([#1687](https://github.com/folke/lazy.nvim/issues/1687)) ([591ef40](https://github.com/folke/lazy.nvim/commit/591ef40f2da3a26fbcc0466988cd6fe45ca68cae))
* **rocks:** add lib64 plugin directory to package.cpath ([#1717](https://github.com/folke/lazy.nvim/issues/1717)) ([80da254](https://github.com/folke/lazy.nvim/commit/80da254e645f579c28394ee0f08f75a9c9481744))
* **rockspec:** allow binary lua files. Fixes [#1800](https://github.com/folke/lazy.nvim/issues/1800) ([408449a](https://github.com/folke/lazy.nvim/commit/408449a59adb8c2a31c32fff606676b32ce4552a))
## [11.14.1](https://github.com/folke/lazy.nvim/compare/v11.14.0...v11.14.1) (2024-07-25)
### Bug Fixes
* **plugins:** "Vim:E150: Not a directory" on plugin update ([#1679](https://github.com/folke/lazy.nvim/issues/1679)) ([7108809](https://github.com/folke/lazy.nvim/commit/7108809ab18dc1b1e6f402b29e2e1d35a5d311d5))
## [11.14.0](https://github.com/folke/lazy.nvim/compare/v11.13.5...v11.14.0) (2024-07-24)
### Features
* added `opts.git.cooldown` to allow updating plugins on slow connections. Fixes [#1656](https://github.com/folke/lazy.nvim/issues/1656) ([d5686ef](https://github.com/folke/lazy.nvim/commit/d5686efbd00942b3e38de7c08b8df69d961b02f0))
* **plugin:** improve error handling and show better error message ([c02268a](https://github.com/folke/lazy.nvim/commit/c02268ac6e6aab92249d020d75efc588bd9d24fa))
### Bug Fixes
* **plugin:** make .lazy.lua work again ([b4a5a12](https://github.com/folke/lazy.nvim/commit/b4a5a1209e4c64fa67aedf721a383541a64056d1))
## [11.13.5](https://github.com/folke/lazy.nvim/compare/v11.13.4...v11.13.5) (2024-07-22)
### Bug Fixes
* **health:** dont use vim.fn.system to get cmd versions ([7d29719](https://github.com/folke/lazy.nvim/commit/7d29719ade6f5a269e3b7d08b246641b5b079aaa))
## [11.13.4](https://github.com/folke/lazy.nvim/compare/v11.13.3...v11.13.4) (2024-07-22)
### Bug Fixes
* **loader:** add plugins whose rtp got loaded early to start plugins ([34b0126](https://github.com/folke/lazy.nvim/commit/34b0126e5b3966f1dbe148d6f8450213115e76b2))
* **loader:** explicitely set package.loaded.modname to nil to prevent recursive loading errors ([12f2c74](https://github.com/folke/lazy.nvim/commit/12f2c74244cc768d97c83972aa63722389b5d96d))
## [11.13.3](https://github.com/folke/lazy.nvim/compare/v11.13.2...v11.13.3) (2024-07-21)
### Reverts
* fix(loader): add auto loaded module to package.loaded early to prevent require loops ([a692bf8](https://github.com/folke/lazy.nvim/commit/a692bf86883457f45fe3f773bfc8bc4d9e4b070c))
## [11.13.2](https://github.com/folke/lazy.nvim/compare/v11.13.1...v11.13.2) (2024-07-21)
### Bug Fixes
* **loader:** add auto loaded module to package.loaded early to prevent require loops ([18d1c1b](https://github.com/folke/lazy.nvim/commit/18d1c1b47e175cd58dc12bf4792ef4e9a50505fa))
## [11.13.1](https://github.com/folke/lazy.nvim/compare/v11.13.0...v11.13.1) (2024-07-19)
### Bug Fixes
* **build:** only load the plugin before build for `:` build commands ([5bdb12a](https://github.com/folke/lazy.nvim/commit/5bdb12a038e5a72cc793f38893f1a9c9fb741759))
## [11.13.0](https://github.com/folke/lazy.nvim/compare/v11.12.0...v11.13.0) (2024-07-17)
### Features
* **ui:** added mapping descriptions ([6ca90a2](https://github.com/folke/lazy.nvim/commit/6ca90a21202808796418e46d3cebfbb5a44e54a2))
## [11.12.0](https://github.com/folke/lazy.nvim/compare/v11.11.1...v11.12.0) (2024-07-16)
### Features
* **git:** added git network throttle to limit network related git ops per interval. Closes [#1635](https://github.com/folke/lazy.nvim/issues/1635) ([d731a6b](https://github.com/folke/lazy.nvim/commit/d731a6b005fd239e85e555bd57362382f6c1e461))
## [11.11.1](https://github.com/folke/lazy.nvim/compare/v11.11.0...v11.11.1) (2024-07-13)
### Bug Fixes
* **config:** check for lib64. Fixes [#1343](https://github.com/folke/lazy.nvim/issues/1343) ([93499c5](https://github.com/folke/lazy.nvim/commit/93499c5deb37641c6cf71528a93f101d186b409f))
* **lockfile:** ensure newline at EOF for lockfile ([#1639](https://github.com/folke/lazy.nvim/issues/1639)) ([7ed9f71](https://github.com/folke/lazy.nvim/commit/7ed9f7173cdec71a057053d7e6efc20c2c230b95))
## [11.11.0](https://github.com/folke/lazy.nvim/compare/v11.10.4...v11.11.0) (2024-07-11)
### Features
* add plugin name to handlers.managed ([17473db](https://github.com/folke/lazy.nvim/commit/17473db1d79ea30e06126834be7fd95ca511557b))
### Bug Fixes
* **minit:** add tests to package.path when running busted (helpers.lua etc) ([fadebdc](https://github.com/folke/lazy.nvim/commit/fadebdc76b71a1d3658a88a025c6c8fb4749e0f8))
* **util:** strip `-lua` in normname ([54b003c](https://github.com/folke/lazy.nvim/commit/54b003c650f07b771e61566f7be2629beb2b781f))
## [11.10.4](https://github.com/folke/lazy.nvim/compare/v11.10.3...v11.10.4) (2024-07-08)
### Bug Fixes
* **rocks:** try building anyway even when prerequisits have not been met. (will likely fail) ([f0324de](https://github.com/folke/lazy.nvim/commit/f0324defdd43be8aa14aaf3a794ff3d5581f36ba))
* **ui:** don't treat suspended as headless. Closes [#1626](https://github.com/folke/lazy.nvim/issues/1626) ([2dfccd7](https://github.com/folke/lazy.nvim/commit/2dfccd7b948beb26d8bcff7f9113a3a5c85cbc4a))
## [11.10.3](https://github.com/folke/lazy.nvim/compare/v11.10.2...v11.10.3) (2024-07-07)
### Bug Fixes
* **git:** local plugin fixes ([#1624](https://github.com/folke/lazy.nvim/issues/1624)) ([72c0dc9](https://github.com/folke/lazy.nvim/commit/72c0dc9462ab3bf1a68198afabc1eb4e2940d299))
## [11.10.2](https://github.com/folke/lazy.nvim/compare/v11.10.1...v11.10.2) (2024-07-07)
### Bug Fixes
* **git:** only check for new commits for local plugins. Closes [#1512](https://github.com/folke/lazy.nvim/issues/1512) ([81d2bff](https://github.com/folke/lazy.nvim/commit/81d2bfffdc8c84a40d25cae7fd4800178c19a138))
## [11.10.1](https://github.com/folke/lazy.nvim/compare/v11.10.0...v11.10.1) (2024-07-05)
### Bug Fixes
* **lockfile:** keep cond=false and enabed=false in lockfile. Fixes [#1535](https://github.com/folke/lazy.nvim/issues/1535). Fixes [#1606](https://github.com/folke/lazy.nvim/issues/1606) ([baac551](https://github.com/folke/lazy.nvim/commit/baac5517770abd6eee63d11cf4791ef5bf5702e8))
## [11.10.0](https://github.com/folke/lazy.nvim/compare/v11.9.2...v11.10.0) (2024-07-04)
### Features
* **profiling:** merge VeryLazy stats and show startuptime in profile view ([0f2786b](https://github.com/folke/lazy.nvim/commit/0f2786bcc91347188627534471ee75c3f6f16b2d))
### Bug Fixes
* **config:** determine headless only during startup. Fixes [#1608](https://github.com/folke/lazy.nvim/issues/1608) ([6fdd904](https://github.com/folke/lazy.nvim/commit/6fdd904ee45b66d933c5d2f72bcec337e13744f8))
* **plugin:** local spec name ([923e1aa](https://github.com/folke/lazy.nvim/commit/923e1aa7a49d945afa4c03da4f8ff052cd6d14a6))
## [11.9.2](https://github.com/folke/lazy.nvim/compare/v11.9.1...v11.9.2) (2024-07-02)
### Bug Fixes
* **async:** make asyncs abortable ([1fad617](https://github.com/folke/lazy.nvim/commit/1fad61712bd3937dda925775a7736b8efbcbf1a7))
* **health:** check for errors when executing commands. Closes [#1599](https://github.com/folke/lazy.nvim/issues/1599) ([d0921f5](https://github.com/folke/lazy.nvim/commit/d0921f5b9b3d2c5e09618da55a018228edcc4d16))
### Performance Improvements
* **plugin:** minor optim to resolve imports a bit faster ([a9d7ade](https://github.com/folke/lazy.nvim/commit/a9d7ade203b3f3ee3058c082c62afdf8e4bcb416))
## [11.9.1](https://github.com/folke/lazy.nvim/compare/v11.9.0...v11.9.1) (2024-06-30)
### Performance Improvements
* automatically suspend the scheduler when all threads are waiting ([#1591](https://github.com/folke/lazy.nvim/issues/1591)) ([c7ed87f](https://github.com/folke/lazy.nvim/commit/c7ed87f9ca03ea412134d6a6ea55b43232eb6b0c))
* suspend when tasks are active ([2f4ac03](https://github.com/folke/lazy.nvim/commit/2f4ac035bcc66292250de7134d73007b147f64e8))
## [11.9.0](https://github.com/folke/lazy.nvim/compare/v11.8.2...v11.9.0) (2024-06-29)
### Features
* **ui:** use [[ & ]] to navigate between plugins. Fixes [#1463](https://github.com/folke/lazy.nvim/issues/1463) ([5e3c112](https://github.com/folke/lazy.nvim/commit/5e3c112cb32c9cb6e8622aab4446358e039def7c))
### Bug Fixes
* **ui:** when closing details, jump to plugin header. Closes [#1338](https://github.com/folke/lazy.nvim/issues/1338) ([3772914](https://github.com/folke/lazy.nvim/commit/37729140751577e87318c137d90d0e6bb00ceff1))
## [11.8.2](https://github.com/folke/lazy.nvim/compare/v11.8.1...v11.8.2) (2024-06-29)
### Bug Fixes
* **process:** deal with process errors ([a75d950](https://github.com/folke/lazy.nvim/commit/a75d950b8f356733ad2d20c4bdb794179e6d4ff1))
* **ui:** save/restore view right before/after rendering ([5d334b9](https://github.com/folke/lazy.nvim/commit/5d334b9f579aacd09603dd9e19b6730fbfcf4c72))
### Performance Improvements
* **rocks:** `vim.fn.executable` is slow on WSL2, so only check for `luarocks` when needed. Closes [#1585](https://github.com/folke/lazy.nvim/issues/1585) ([9ab3061](https://github.com/folke/lazy.nvim/commit/9ab306169060eeab7ebca00653318683e72ab62d))
## [11.8.1](https://github.com/folke/lazy.nvim/compare/v11.8.0...v11.8.1) (2024-06-29)
### Bug Fixes
* **async:** remove debug assert ([3513227](https://github.com/folke/lazy.nvim/commit/3513227a9a41c8e6366e1719f4cefbe891ca73d2))
## [11.8.0](https://github.com/folke/lazy.nvim/compare/v11.7.0...v11.8.0) (2024-06-29)
### Features
* **plugin:** allow loading specs without pkg ([695a058](https://github.com/folke/lazy.nvim/commit/695a05872a5b44e366e5532eb2fe38a64fae8357))
## [11.7.0](https://github.com/folke/lazy.nvim/compare/v11.6.0...v11.7.0) (2024-06-29) ## [11.7.0](https://github.com/folke/lazy.nvim/compare/v11.6.0...v11.7.0) (2024-06-29)

View File

@ -1,4 +1,4 @@
-- Lazy Bootstrapper -- Lay Bootstrapper
-- Usage: -- Usage:
-- ```lua -- ```lua
-- load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))() -- load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
@ -6,20 +6,15 @@
local M = {} local M = {}
function M.setup() function M.setup()
local uv = vim.uv or vim.loop
if vim.env.LAZY_STDPATH then if vim.env.LAZY_STDPATH then
local root = vim.fn.fnamemodify(vim.env.LAZY_STDPATH, ":p"):gsub("[\\/]$", "") local root = vim.fn.fnamemodify(vim.env.LAZY_STDPATH, ":p")
for _, name in ipairs({ "config", "data", "state", "cache" }) do 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 end
end end
if vim.env.LAZY_PATH and not uv.fs_stat(vim.env.LAZY_PATH) then
vim.env.LAZY_PATH = nil
end
local lazypath = vim.env.LAZY_PATH or vim.fn.stdpath("data") .. "/lazy/lazy.nvim" local lazypath = vim.env.LAZY_PATH or vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.env.LAZY_PATH and not uv.fs_stat(lazypath) then if not vim.env.LAZY_PATH and not (vim.uv or vim.loop).fs_stat(lazypath) then
vim.api.nvim_echo({ vim.api.nvim_echo({
{ {
"Cloning lazy.nvim\n\n", "Cloning lazy.nvim\n\n",
@ -27,21 +22,23 @@ function M.setup()
}, },
}, true, {}) }, true, {})
local lazyrepo = "https://github.com/folke/lazy.nvim.git" local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local ok, out = pcall(vim.fn.system, { local ok, out =
"git", pcall(vim.fn.system, { "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
"clone",
"--filter=blob:none",
lazyrepo,
lazypath,
})
if not ok or vim.v.shell_error ~= 0 then if not ok or vim.v.shell_error ~= 0 then
vim.api.nvim_echo({ vim.api.nvim_echo({
{ "Failed to clone lazy.nvim\n", "ErrorMsg" }, {
{ vim.trim(out or ""), "WarningMsg" }, "Failed to clone lazy.nvim\n",
{ "\nPress any key to exit...", "MoreMsg" }, "ErrorMsg",
},
{
vim.trim(out or ""),
"WarningMsg",
},
{ "\nPress any key to exit", "MoreMsg" },
}, true, {}) }, true, {})
vim.fn.getchar() vim.fn.getchar()
os.exit(1) vim.cmd([[quit]])
end end
end end
vim.opt.rtp:prepend(lazypath) vim.opt.rtp:prepend(lazypath)

View File

@ -39,7 +39,6 @@ Table of Contents *lazy.nvim-table-of-contents*
8. 🔥 Developers |lazy.nvim-🔥-developers| 8. 🔥 Developers |lazy.nvim-🔥-developers|
- Best Practices |lazy.nvim-🔥-developers-best-practices| - Best Practices |lazy.nvim-🔥-developers-best-practices|
- Building |lazy.nvim-🔥-developers-building| - Building |lazy.nvim-🔥-developers-building|
- Minit (Minimal Init) |lazy.nvim-🔥-developers-minit-(minimal-init)|
9. Links |lazy.nvim-links| 9. Links |lazy.nvim-links|
============================================================================== ==============================================================================
@ -157,16 +156,7 @@ STRUCTURED SETUP *lazy.nvim-🛠️-installation-structured-setup*
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git" local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end end
vim.opt.rtp:prepend(lazypath) vim.opt.rtp:prepend(lazypath)
@ -205,16 +195,7 @@ SINGLE FILE SETUP *lazy.nvim-🛠️-installation-single-file-setup*
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git" local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end end
vim.opt.rtp:prepend(lazypath) vim.opt.rtp:prepend(lazypath)
@ -291,25 +272,23 @@ SPEC LOADING *lazy.nvim-🔌-plugin-spec-spec-loading*
SPEC SETUP *lazy.nvim-🔌-plugin-spec-spec-setup* SPEC SETUP *lazy.nvim-🔌-plugin-spec-spec-setup*
-------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
Property Type Description Property Type Description
---------- ----------------------------- --------------------------------------------------------- ---------- ----------------------------- ----------------------------------------------------------
init fun(LazyPlugin) init functions are always executed during startup. Mostly init fun(LazyPlugin) init functions are always executed during startup
useful for setting vim.g.* configuration used by Vim
plugins startup
opts table or opts should be a table (will be merged with parent opts table or opts should be a table (will be merged with parent specs),
fun(LazyPlugin, opts:table) specs), return a table (replaces parent specs) or should fun(LazyPlugin, opts:table) return a table (replaces parent specs) or should change a
change a table. The table will be passed to the table. The table will be passed to the Plugin.config()
Plugin.config() function. Setting this value will imply function. Setting this value will imply Plugin.config()
Plugin.config()
config fun(LazyPlugin, opts:table) config is executed when the plugin loads. The default config fun(LazyPlugin, opts:table) config is executed when the plugin loads. The default
or true implementation will automatically run or true implementation will automatically run
require(MAIN).setup(opts) if opts or config = true is require(MAIN).setup(opts) if opts or config = true is set.
set. Lazy uses several heuristics to determine the Lazy uses several heuristics to determine the plugins
plugins MAIN module automatically based on the plugins MAIN module automatically based on the plugins name. See
name. (opts is the recommended way to configure plugins). 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 main string? You can specify the main module to use for config() and
opts(), in case it can not be determined automatically. opts(), in case it can not be determined automatically.
@ -318,12 +297,7 @@ SPEC SETUP *lazy.nvim-🔌-plugin-spec-spec-setup*
build fun(LazyPlugin) or string or build is executed when a plugin is installed or updated. build fun(LazyPlugin) or string or build is executed when a plugin is installed or updated.
false or a list of build See Building for more information. false or a list of build See Building for more information.
commands commands
-------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
Always use `opts` instead of `config` when possible. `config` is almost never
needed.
SPEC LAZY LOADING *lazy.nvim-🔌-plugin-spec-spec-lazy-loading* SPEC LAZY LOADING *lazy.nvim-🔌-plugin-spec-spec-lazy-loading*
@ -540,7 +514,9 @@ function.
keys = { keys = {
{ "<leader>ft", "<cmd>Neotree toggle<cr>", desc = "NeoTree" }, { "<leader>ft", "<cmd>Neotree toggle<cr>", desc = "NeoTree" },
}, },
opts = {}, config = function()
require("neo-tree").setup()
end,
} }
< <
@ -644,42 +620,24 @@ will be added to the plugins spec.
-- then set the below to false. This should work, but is NOT supported and will -- then set the below to false. This should work, but is NOT supported and will
-- increase downloads a lot. -- increase downloads a lot.
filter = true, filter = true,
-- rate of network related git operations (clone, fetch, checkout)
throttle = {
enabled = false, -- not enabled by default
-- max 2 ops every 5 seconds
rate = 2,
duration = 5 * 1000, -- in ms
},
-- Time in seconds to wait before running fetch again for a plugin.
-- Repeated update/check operations will not run again until this
-- cooldown period has passed.
cooldown = 0,
}, },
pkg = { pkg = {
enabled = true, enabled = true,
cache = vim.fn.stdpath("state") .. "/lazy/pkg-cache.lua", cache = vim.fn.stdpath("state") .. "/lazy/pkg-cache.lua",
versions = true, -- Honor versions in pkg sources
-- the first package source that is found for a plugin will be used. -- the first package source that is found for a plugin will be used.
sources = { sources = {
"lazy", "lazy",
"rockspec", -- will only be used when rocks.enabled is true "rockspec",
"packspec", "packspec",
}, },
}, },
rocks = { rocks = {
enabled = true,
root = vim.fn.stdpath("data") .. "/lazy-rocks", root = vim.fn.stdpath("data") .. "/lazy-rocks",
server = "https://lumen-oss.github.io/rocks-binaries/", server = "https://nvim-neorocks.github.io/rocks-binaries/",
-- use hererocks to install luarocks?
-- set to `nil` to use hererocks when luarocks is not found
-- set to `true` to always use hererocks
-- set to `false` to always use luarocks
hererocks = nil,
}, },
dev = { dev = {
-- Directory where you store your local plugin projects. If a function is used, ---@type string | fun(plugin: LazyPlugin): string directory where you store your local plugin projects
-- the plugin directory (e.g. `~/projects/plugin-name`) must be returned.
---@type string | fun(plugin: LazyPlugin): string
path = "~/projects", path = "~/projects",
---@type string[] plugins that match these patterns will use your local versions instead of being fetched from GitHub ---@type string[] plugins that match these patterns will use your local versions instead of being fetched from GitHub
patterns = {}, -- For example {"folke"} patterns = {}, -- For example {"folke"}
@ -706,7 +664,6 @@ will be added to the plugins spec.
icons = { icons = {
cmd = " ", cmd = " ",
config = "", config = "",
debug = "● ",
event = " ", event = " ",
favorite = " ", favorite = " ",
ft = " ", ft = " ",
@ -732,7 +689,7 @@ will be added to the plugins spec.
-- leave nil, to automatically select a browser depending on your OS. -- leave nil, to automatically select a browser depending on your OS.
-- If you want to use a specific browser, you can define it here -- If you want to use a specific browser, you can define it here
browser = nil, ---@type string? browser = nil, ---@type string?
throttle = 1000 / 30, -- how frequently should the ui process render events throttle = 20, -- how frequently should the ui process render events
custom_keys = { custom_keys = {
-- You can define custom key maps here. If present, the description will -- You can define custom key maps here. If present, the description will
-- be shown in the help menu. -- be shown in the help menu.
@ -747,16 +704,6 @@ will be added to the plugins spec.
desc = "Open lazygit log", desc = "Open lazygit log",
}, },
["<localleader>i"] = {
function(plugin)
Util.notify(vim.inspect(plugin), {
title = "Inspect " .. plugin.name,
lang = "lua",
})
end,
desc = "Inspect Plugin",
},
["<localleader>t"] = { ["<localleader>t"] = {
function(plugin) function(plugin)
require("lazy.util").float_term(nil, { require("lazy.util").float_term(nil, {
@ -767,17 +714,6 @@ will be added to the plugins spec.
}, },
}, },
}, },
-- Output options for headless mode
headless = {
-- show the output from process commands like git
process = true,
-- show log messages
log = true,
-- show task start/end
task = true,
-- use ansi colors
colors = true,
},
diff = { diff = {
-- diff command <d> can be one of: -- diff command <d> can be one of:
-- * browser: opens the github compare view. Note that this is always mapped to <K> as well, -- * browser: opens the github compare view. Note that this is always mapped to <K> as well,
@ -829,7 +765,7 @@ will be added to the plugins spec.
enabled = true, enabled = true,
root = vim.fn.stdpath("state") .. "/lazy/readme", root = vim.fn.stdpath("state") .. "/lazy/readme",
files = { "README.md", "lua/**/README.md" }, files = { "README.md", "lua/**/README.md" },
-- only generate markdown helptags for plugins that don't have docs -- only generate markdown helptags for plugins that dont have docs
skip_if_doc_exists = true, skip_if_doc_exists = true,
}, },
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things
@ -875,8 +811,6 @@ If you dont want to use a Nerd Font, you can replace the icons with Unicode s
----------------------------------------------------------------------- -----------------------------------------------------------------------
Highlight Group Default Group Description Highlight Group Default Group Description
----------------------- ----------------------- ----------------------- ----------------------- ----------------------- -----------------------
LazyBold { bold = true }
LazyButton CursorLine LazyButton CursorLine
LazyButtonActive Visual LazyButtonActive Visual
@ -897,16 +831,10 @@ If you dont want to use a Nerd Font, you can replace the icons with Unicode s
LazyDir @markup.link directory LazyDir @markup.link directory
LazyError DiagnosticError task errors
LazyH1 IncSearch home button LazyH1 IncSearch home button
LazyH2 Bold titles LazyH2 Bold titles
LazyInfo DiagnosticInfo task errors
LazyItalic { italic = true }
LazyLocal Constant LazyLocal Constant
LazyNoCond DiagnosticWarn unloaded icon for a LazyNoCond DiagnosticWarn unloaded icon for a
@ -943,13 +871,13 @@ If you dont want to use a Nerd Font, you can replace the icons with Unicode s
LazySpecial @punctuation.special LazySpecial @punctuation.special
LazyTaskError ErrorMsg task errors
LazyTaskOutput MsgArea task output LazyTaskOutput MsgArea task output
LazyUrl @markup.link url LazyUrl @markup.link url
LazyValue @string value of a property LazyValue @string value of a property
LazyWarning DiagnosticWarn task errors
----------------------------------------------------------------------- -----------------------------------------------------------------------
============================================================================== ==============================================================================
@ -1294,8 +1222,6 @@ BEST PRACTICES *lazy.nvim-🔥-developers-best-practices*
>lua >lua
{ "nvim-lua/plenary.nvim", lazy = true } { "nvim-lua/plenary.nvim", lazy = true }
< <
- Always use `opts` instead of `config` when possible. `config` is almost never
needed.
- Only use `dependencies` if a plugin needs the dep to be installed **AND** - Only use `dependencies` if a plugin needs the dep to be installed **AND**
loaded. Lua plugins/libraries are automatically loaded when they are loaded. Lua plugins/libraries are automatically loaded when they are
`require()`d, so they dont need to be in `dependencies`. `require()`d, so they dont need to be in `dependencies`.
@ -1334,90 +1260,6 @@ Use `vim.log.levels.TRACE` to only show the message as a **status** message for
the task. the task.
MINIT (MINIMAL INIT) *lazy.nvim-🔥-developers-minit-(minimal-init)*
**lazy.nvim** comes with some built-in functionality to help you create a
minimal init for your plugin.
I mainly use this for testing and for users to create a `repro.lua`.
When running in **headless** mode, **lazy.nvim** will log any messages to the
terminal. See `opts.headless` for more info.
**minit** will install/load all your specs and will always run an update as
well.
BOOTSTRAP ~
>lua
-- setting this env will override all XDG paths
vim.env.LAZY_STDPATH = ".tests"
-- this will install lazy in your stdpath
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
<
TESTING WITH BUSTED ~
This will add `"lunarmodules/busted"`, configure `hererocks` and run `busted`.
Below is an example of how I use **minit** to run tests with busted
<https://olivinelabs.com/busted/> in **LazyVim**.
>lua
#!/usr/bin/env -S nvim -l
vim.env.LAZY_STDPATH = ".tests"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
-- Setup lazy.nvim
require("lazy.minit").busted({
spec = {
"LazyVim/starter",
"williamboman/mason-lspconfig.nvim",
"williamboman/mason.nvim",
"nvim-treesitter/nvim-treesitter",
},
})
<
To use this, you can run:
>sh
nvim -l ./tests/busted.lua tests
<
If you want to inspect the test environment, run:
>sh
nvim -u ./tests/busted.lua
<
REPRO.LUA ~
>lua
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
require("lazy.minit").repro({
spec = {
"stevearc/conform.nvim",
"nvim-neotest/nvim-nio",
},
})
-- do anything else you need to do to reproduce the issue
<
Then run it with:
>sh
nvim -u repro.lua
<
============================================================================== ==============================================================================
9. Links *lazy.nvim-links* 9. Links *lazy.nvim-links*

View File

@ -1,14 +1,11 @@
local Util = require("lazy.core.util")
local M = {} local M = {}
---@type Async[] ---@type Async[]
M._active = {} M._queue = {}
---@type Async[] M._executor = assert(vim.loop.new_timer())
M._suspended = {}
M._executor = assert(vim.loop.new_check())
M.BUDGET = 10 M.TIMER = 10
M.BUDGET = 100
---@type table<thread, Async> ---@type table<thread, Async>
M._threads = setmetatable({}, { __mode = "k" }) M._threads = setmetatable({}, { __mode = "k" })
@ -45,6 +42,11 @@ function Async:init(fn)
return M.add(self) return M.add(self)
end end
function Async:restart()
assert(not self:running(), "Cannot restart a running async")
self:init(self._fn)
end
---@param event AsyncEvent ---@param event AsyncEvent
---@param cb async fun(res:any, async:Async) ---@param cb async fun(res:any, async:Async)
function Async:on(event, cb) function Async:on(event, cb)
@ -75,41 +77,27 @@ function Async:sleep(ms)
end end
---@async ---@async
---@param yield? boolean function Async:suspend()
function Async:suspend(yield)
self._suspended = true self._suspended = true
if coroutine.running() == self._co and yield ~= false then if coroutine.running() == self._co then
M.yield() coroutine.yield()
end end
end end
function Async:resume() function Async:resume()
self._suspended = false self._suspended = false
M._run()
end end
---@async
---@param yield? boolean
function Async:wake(yield)
local async = M.running()
assert(async, "Not in an async context")
self:on("done", function()
async:resume()
end)
async:suspend(yield)
end
---@async
function Async:wait() function Async:wait()
local async = M.running()
if coroutine.running() == self._co then if coroutine.running() == self._co then
error("Cannot wait on self") error("Cannot wait on self")
end end
local async = M.running() while self:running() do
if async then if async then
self:wake() coroutine.yield()
else else
while self:running() do
vim.wait(10) vim.wait(10)
end end
end end
@ -132,79 +120,42 @@ function Async:step()
return self:running() return self:running()
end end
function M.abort()
for _, async in ipairs(M._active) do
coroutine.resume(async._co, "abort")
end
end
function M.yield()
if coroutine.yield() == "abort" then
error("aborted", 2)
end
end
function M.step() function M.step()
local budget = M.BUDGET * 1e6
local start = vim.uv.hrtime() local start = vim.uv.hrtime()
for _ = 1, #M._active do local count = #M._queue
if Util.exiting() or vim.uv.hrtime() - start > M.BUDGET * 1e6 then local i = 0
while #M._queue > 0 and vim.uv.hrtime() - start < budget do
---@type Async
local state = table.remove(M._queue, 1)
if state:step() then
table.insert(M._queue, state)
end
i = i + 1
if i >= count then
break break
end end
local state = table.remove(M._active, 1)
if state:step() then
if state._suspended then
table.insert(M._suspended, state)
else
table.insert(M._active, state)
end
end
end end
for _ = 1, #M._suspended do if #M._queue == 0 then
local state = table.remove(M._suspended, 1)
table.insert(state._suspended and M._suspended or M._active, state)
end
-- M.debug()
if #M._active == 0 or Util.exiting() then
return M._executor:stop() return M._executor:stop()
end end
end end
function M.debug()
local lines = {
"- active: " .. #M._active,
"- suspended: " .. #M._suspended,
}
for _, async in ipairs(M._active) do
local info = debug.getinfo(async._fn)
local file = vim.fn.fnamemodify(info.short_src:sub(1), ":~:.")
table.insert(lines, ("%s:%d"):format(file, info.linedefined))
if #lines > 10 then
break
end
end
local msg = table.concat(lines, "\n")
M._notif = vim.notify(msg, nil, { replace = M._notif })
end
---@param async Async ---@param async Async
function M.add(async) function M.add(async)
table.insert(M._active, async) table.insert(M._queue, async)
M._run() if not M._executor:is_active() then
return async M._executor:start(1, M.TIMER, vim.schedule_wrap(M.step))
end
function M._run()
if not Util.exiting() and not M._executor:is_active() then
M._executor:start(vim.schedule_wrap(M.step))
end end
return async
end end
function M.running() function M.running()
local co = coroutine.running() local co = coroutine.running()
if co then if co then
return M._threads[co] local async = M._threads[co]
assert(async, "In coroutine without async context")
return async
end end
end end

View File

@ -6,7 +6,6 @@ local Util = require("lazy.util")
local M = {} local M = {}
M.patterns = { "nvim", "treesitter", "tree-sitter", "cmp", "neo" } M.patterns = { "nvim", "treesitter", "tree-sitter", "cmp", "neo" }
local manifest_file = "build/manifest.lua"
function M.fetch(url, file, prefix) function M.fetch(url, file, prefix)
if not vim.uv.fs_stat(file) then if not vim.uv.fs_stat(file) then
@ -20,46 +19,11 @@ function M.fetch(url, file, prefix)
end end
end end
function M.split()
local lines = vim.fn.readfile(manifest_file)
local id = 0
local files = {} ---@type string[]
while #lines > 0 do
id = id + 1
local part_file = "build/manifest-part-" .. id .. ".lua"
local idx = math.min(#lines, 30000)
while idx < #lines and not lines[idx]:match("^ },$") do
idx = idx + 1
end
local part_lines = vim.list_slice(lines, 1, idx)
if idx ~= #lines then
part_lines[#part_lines] = " }}"
end
vim.fn.writefile(part_lines, part_file)
files[#files + 1] = part_file
print("Wrote " .. part_file .. "\n")
lines = vim.list_slice(lines, idx + 1)
if #lines == 0 then
break
end
lines[1] = "repository = { " .. lines[1]
end
return files
end
---@return RockManifest? ---@return RockManifest?
function M.fetch_manifest() function M.fetch_manifest()
local manifest_file = "build/manifest.lua"
M.fetch("https://luarocks.org/manifest-5.1", manifest_file) M.fetch("https://luarocks.org/manifest-5.1", manifest_file)
local ret = { repository = {} } return Rocks.parse(manifest_file)
for _, file in ipairs(M.split()) do
local part = Rocks.parse(file)
print(vim.tbl_count(part.repository or {}) .. " rocks in " .. file .. "\n")
for k, v in pairs(part.repository or {}) do
ret.repository[k] = v
end
end
return ret
end end
function M.fetch_rockspec(name, version, prefix) function M.fetch_rockspec(name, version, prefix)
@ -73,7 +37,6 @@ function M.build()
local manifest = M.fetch_manifest() or {} local manifest = M.fetch_manifest() or {}
---@type {name:string, version:string, url:string}[] ---@type {name:string, version:string, url:string}[]
local nvim_rocks = {} local nvim_rocks = {}
print(vim.tbl_count(manifest.repository or {}) .. " rocks in manifest\n")
for rock, vv in pairs(manifest.repository or {}) do for rock, vv in pairs(manifest.repository or {}) do
local matches = false local matches = false
for _, pattern in ipairs(M.patterns) do for _, pattern in ipairs(M.patterns) do

File diff suppressed because it is too large Load Diff

View File

@ -34,17 +34,6 @@ M.defaults = {
-- then set the below to false. This should work, but is NOT supported and will -- then set the below to false. This should work, but is NOT supported and will
-- increase downloads a lot. -- increase downloads a lot.
filter = true, filter = true,
-- rate of network related git operations (clone, fetch, checkout)
throttle = {
enabled = false, -- not enabled by default
-- max 2 ops every 5 seconds
rate = 2,
duration = 5 * 1000, -- in ms
},
-- Time in seconds to wait before running fetch again for a plugin.
-- Repeated update/check operations will not run again until this
-- cooldown period has passed.
cooldown = 0,
}, },
pkg = { pkg = {
enabled = true, enabled = true,
@ -59,17 +48,12 @@ M.defaults = {
rocks = { rocks = {
enabled = true, enabled = true,
root = vim.fn.stdpath("data") .. "/lazy-rocks", root = vim.fn.stdpath("data") .. "/lazy-rocks",
server = "https://lumen-oss.github.io/rocks-binaries/", server = "https://nvim-neorocks.github.io/rocks-binaries/",
-- use hererocks to install luarocks? -- use hererocks to install luarocks.
-- set to `nil` to use hererocks when luarocks is not found hererocks = vim.fn.executable("luarocks") == 0,
-- set to `true` to always use hererocks
-- set to `false` to always use luarocks
hererocks = nil,
}, },
dev = { dev = {
-- Directory where you store your local plugin projects. If a function is used, ---@type string | fun(plugin: LazyPlugin): string directory where you store your local plugin projects
-- the plugin directory (e.g. `~/projects/plugin-name`) must be returned.
---@type string | fun(plugin: LazyPlugin): string
path = "~/projects", path = "~/projects",
---@type string[] plugins that match these patterns will use your local versions instead of being fetched from GitHub ---@type string[] plugins that match these patterns will use your local versions instead of being fetched from GitHub
patterns = {}, -- For example {"folke"} patterns = {}, -- For example {"folke"}
@ -96,7 +80,6 @@ M.defaults = {
icons = { icons = {
cmd = "", cmd = "",
config = "", config = "",
debug = "",
event = "", event = "",
favorite = "", favorite = "",
ft = "", ft = "",
@ -219,7 +202,7 @@ M.defaults = {
enabled = true, enabled = true,
root = vim.fn.stdpath("state") .. "/lazy/readme", root = vim.fn.stdpath("state") .. "/lazy/readme",
files = { "README.md", "lua/**/README.md" }, files = { "README.md", "lua/**/README.md" },
-- only generate markdown helptags for plugins that don't have docs -- only generate markdown helptags for plugins that dont have docs
skip_if_doc_exists = true, skip_if_doc_exists = true,
}, },
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things
@ -235,14 +218,7 @@ M.defaults = {
debug = false, debug = false,
} }
function M.hererocks() M.version = "11.7.0" -- x-release-please-version
if M.options.rocks.hererocks == nil then
M.options.rocks.hererocks = vim.fn.executable("luarocks") == 0
end
return M.options.rocks.hererocks
end
M.version = "11.17.5" -- x-release-please-version
M.ns = vim.api.nvim_create_namespace("lazy") M.ns = vim.api.nvim_create_namespace("lazy")
@ -267,10 +243,8 @@ M.mapleader = nil
---@type string ---@type string
M.maplocalleader = nil M.maplocalleader = nil
M.suspended = false
function M.headless() function M.headless()
return not M.suspended and #vim.api.nvim_list_uis() == 0 return #vim.api.nvim_list_uis() == 0
end end
---@param opts? LazyConfig ---@param opts? LazyConfig
@ -298,9 +272,6 @@ function M.setup(opts)
M.me = debug.getinfo(1, "S").source:sub(2) M.me = debug.getinfo(1, "S").source:sub(2)
M.me = Util.norm(vim.fn.fnamemodify(M.me, ":p:h:h:h:h")) M.me = Util.norm(vim.fn.fnamemodify(M.me, ":p:h:h:h:h"))
local lib = vim.fn.fnamemodify(vim.v.progpath, ":p:h:h") .. "/lib"
lib = vim.uv.fs_stat(lib .. "64") and (lib .. "64") or lib
lib = lib .. "/nvim"
if M.options.performance.rtp.reset then if M.options.performance.rtp.reset then
---@type vim.Option ---@type vim.Option
vim.opt.rtp = { vim.opt.rtp = {
@ -308,7 +279,7 @@ function M.setup(opts)
vim.fn.stdpath("data") .. "/site", vim.fn.stdpath("data") .. "/site",
M.me, M.me,
vim.env.VIMRUNTIME, vim.env.VIMRUNTIME,
lib, vim.fn.fnamemodify(vim.v.progpath, ":p:h:h") .. "/lib/nvim",
vim.fn.stdpath("config") .. "/after", vim.fn.stdpath("config") .. "/after",
} }
end end
@ -356,12 +327,6 @@ function M.setup(opts)
end end
end, end,
}) })
vim.api.nvim_create_autocmd({ "VimSuspend", "VimResume" }, {
callback = function(ev)
M.suspended = ev.event == "VimSuspend"
end,
})
end, end,
}) })
end end

View File

@ -75,9 +75,7 @@ function M:_add(event)
end end
-- HACK: work-around for https://github.com/neovim/neovim/issues/25526 -- HACK: work-around for https://github.com/neovim/neovim/issues/25526
done = true done = true
if event.id ~= "VeryLazy" then Util.track({ [self.type] = event.id })
Util.track({ [self.type] = event.id })
end
local state = M.get_state(ev.event, ev.buf, ev.data) local state = M.get_state(ev.event, ev.buf, ev.data)
@ -88,9 +86,7 @@ function M:_add(event)
for _, s in ipairs(state) do for _, s in ipairs(state) do
M.trigger(s) M.trigger(s)
end end
if event.id ~= "VeryLazy" then Util.track()
Util.track()
end
end, end,
}) })
end end

View File

@ -5,7 +5,7 @@ local Util = require("lazy.core.util")
---@field type LazyHandlerTypes ---@field type LazyHandlerTypes
---@field extends? LazyHandler ---@field extends? LazyHandler
---@field active table<string,table<string,string>> ---@field active table<string,table<string,string>>
---@field managed table<string,string> mapping handler keys to plugin names ---@field managed table<string,string>
---@field super LazyHandler ---@field super LazyHandler
local M = {} local M = {}
@ -114,7 +114,7 @@ function M:add(plugin)
if not self.active[key] then if not self.active[key] then
self.active[key] = {} self.active[key] = {}
self:_add(value) self:_add(value)
self.managed[key] = plugin.name self.managed[key] = key
end end
self.active[key][plugin.name] = plugin.name self.active[key][plugin.name] = plugin.name
end end

View File

@ -11,7 +11,7 @@ local Util = require("lazy.core.util")
---@class LazyKeysSpec: LazyKeysBase ---@class LazyKeysSpec: LazyKeysBase
---@field [1] string lhs ---@field [1] string lhs
---@field [2]? string|fun():string?|false rhs ---@field [2]? string|fun()|false rhs
---@field mode? string|string[] ---@field mode? string|string[]
---@class LazyKeys: LazyKeysBase ---@class LazyKeys: LazyKeysBase

View File

@ -161,7 +161,7 @@ function M.get_start_plugins()
---@type LazyPlugin[] ---@type LazyPlugin[]
local start = {} local start = {}
for _, plugin in pairs(Config.plugins) do for _, plugin in pairs(Config.plugins) do
if not plugin._.loaded and (plugin._.rtp_loaded or plugin.lazy == false) then if plugin.lazy == false and not plugin._.loaded then
start[#start + 1] = plugin start[#start + 1] = plugin
end end
end end
@ -341,9 +341,7 @@ function M._load(plugin, reason, opts)
Util.track({ plugin = plugin.name, start = reason.start }) Util.track({ plugin = plugin.name, start = reason.start })
Handler.disable(plugin) Handler.disable(plugin)
if not plugin.virtual then M.add_to_rtp(plugin)
M.add_to_rtp(plugin)
end
if plugin._.pkg and plugin._.pkg.source == "rockspec" then if plugin._.pkg and plugin._.pkg.source == "rockspec" then
M.add_to_luapath(plugin) M.add_to_luapath(plugin)
@ -355,9 +353,7 @@ function M._load(plugin, reason, opts)
end, "Failed to load deps for " .. plugin.name) end, "Failed to load deps for " .. plugin.name)
end end
if not plugin.virtual then M.packadd(plugin.dir)
M.packadd(plugin.dir)
end
if plugin.config or plugin.opts then if plugin.config or plugin.opts then
M.config(plugin) M.config(plugin)
end end
@ -497,11 +493,8 @@ function M.add_to_luapath(plugin)
local root = Config.options.rocks.root .. "/" .. plugin.name local root = Config.options.rocks.root .. "/" .. plugin.name
local path = root .. "/share/lua/5.1" local path = root .. "/share/lua/5.1"
local cpath = root .. "/lib/lua/5.1" local cpath = root .. "/lib/lua/5.1"
local cpath2 = root .. "/lib64/lua/5.1"
package.path = package.path .. ";" .. path .. "/?.lua;" .. path .. "/?/init.lua;" package.path = package.path .. ";" .. path .. "/?.lua;" .. path .. "/?/init.lua;"
package.cpath = package.cpath .. ";" .. cpath .. "/?." .. (jit.os:find("Windows") and "dll" or "so") .. ";" package.cpath = package.cpath .. ";" .. cpath .. "/?." .. (jit.os:find("Windows") and "dll" or "so") .. ";"
package.cpath = package.cpath .. ";" .. cpath2 .. "/?." .. (jit.os:find("Windows") and "dll" or "so") .. ";"
end end
function M.source(path) function M.source(path)
@ -559,8 +552,6 @@ function M.loader(modname)
end end
if ret then if ret then
-- explicitly set to nil to prevent loading errors
package.loaded[modname] = nil
M.auto_load(modname, ret.modpath) M.auto_load(modname, ret.modpath)
local mod = package.loaded[modname] local mod = package.loaded[modname]
if type(mod) == "table" then if type(mod) == "table" then

View File

@ -179,7 +179,6 @@ function M:_rebuild(name)
local super = nil local super = nil
plugin.url = nil plugin.url = nil
plugin._.dep = true plugin._.dep = true
plugin._.top = true
plugin.optional = true plugin.optional = true
assert(#plugin._.frags > 0, "no fragments found for plugin " .. name) assert(#plugin._.frags > 0, "no fragments found for plugin " .. name)
@ -196,7 +195,6 @@ function M:_rebuild(name)
plugin._.dep = plugin._.dep and fragment.dep plugin._.dep = plugin._.dep and fragment.dep
plugin.optional = plugin.optional and (rawget(fragment.spec, "optional") == true) plugin.optional = plugin.optional and (rawget(fragment.spec, "optional") == true)
plugin.url = fragment.url or plugin.url plugin.url = fragment.url or plugin.url
plugin._.top = plugin._.top and fragment.pid == nil
-- dependencies -- dependencies
for _, dep in ipairs(fragment.deps or {}) do for _, dep in ipairs(fragment.deps or {}) do
@ -215,8 +213,6 @@ function M:_rebuild(name)
plugin.dir = super.dir plugin.dir = super.dir
if plugin.dir then if plugin.dir then
plugin.dir = Util.norm(plugin.dir) plugin.dir = Util.norm(plugin.dir)
elseif super.virtual then
plugin.dir = Util.norm("/dev/null/" .. plugin.name)
else else
if plugin.dev == nil and plugin.url then if plugin.dev == nil and plugin.url then
for _, pattern in ipairs(Config.options.dev.patterns) do for _, pattern in ipairs(Config.options.dev.patterns) do
@ -304,26 +300,13 @@ end
--- Removes plugins that are disabled. --- Removes plugins that are disabled.
function M:fix_disabled() function M:fix_disabled()
local changes = 0 local changes = 0
local function check(top) for _, plugin in pairs(self.plugins) do
for _, plugin in pairs(self.plugins) do if plugin.enabled == false or (type(plugin.enabled) == "function" and not plugin.enabled()) then
if (plugin._.top or false) == top then changes = changes + 1
if plugin.enabled == false or (type(plugin.enabled) == "function" and not plugin.enabled()) then self:disable(plugin)
changes = changes + 1
if plugin.optional then
self:del(plugin.name)
else
self:disable(plugin)
end
self:rebuild()
end
end
end end
end end
-- disable top-level plugins first, since they may have non-top-level frags self:rebuild()
-- that disable other plugins
check(true)
-- then disable non-top-level plugins
check(false)
return changes return changes
end end

View File

@ -21,7 +21,7 @@ M.Spec = Spec
M.LOCAL_SPEC = ".lazy.lua" M.LOCAL_SPEC = ".lazy.lua"
---@param spec? LazySpec ---@param spec? LazySpec
---@param opts? {optional?:boolean, pkg?:boolean} ---@param opts? {optional?:boolean}
function Spec.new(spec, opts) function Spec.new(spec, opts)
local self = setmetatable({}, Spec) local self = setmetatable({}, Spec)
self.meta = Meta.new(self) self.meta = Meta.new(self)
@ -30,9 +30,7 @@ function Spec.new(spec, opts)
self.notifs = {} self.notifs = {}
self.ignore_installed = {} self.ignore_installed = {}
self.optional = opts and opts.optional self.optional = opts and opts.optional
if not (opts and opts.pkg == false) then self.meta:load_pkgs()
self.meta:load_pkgs()
end
if spec then if spec then
self:parse(spec) self:parse(spec)
end end
@ -146,47 +144,30 @@ function Spec:import(spec)
local imported = 0 local imported = 0
---@type {modname: string, load: fun():(LazyPluginSpec?, string?)}[] ---@type (string|(fun():LazyPluginSpec))[]
local modspecs = {} local modspecs = {}
if type(import) == "string" then if type(import) == "string" then
Util.lsmod(import, function(modname, modpath) Util.lsmod(import, function(modname)
modspecs[#modspecs + 1] = { modspecs[#modspecs + 1] = modname
modname = modname,
load = function()
local mod, err = loadfile(modpath)
if mod then
local ret, foo = mod()
if foo then
return nil, "Spec module returned more than one value. Expected a single value."
end
return ret
else
return nil, err
end
end,
}
end)
table.sort(modspecs, function(a, b)
return a.modname < b.modname
end) end)
table.sort(modspecs)
else else
modspecs = { { modname = import_name, load = spec.import } } modspecs = { spec.import }
end end
for _, modspec in ipairs(modspecs) do for _, modspec in ipairs(modspecs) do
imported = imported + 1 imported = imported + 1
local modname = modspec.modname local modname = type(modspec) == "string" and modspec or import_name
Util.track({ import = modname }) Util.track({ import = modname })
self.importing = modname self.importing = modname
-- unload the module so we get a clean slate -- unload the module so we get a clean slate
---@diagnostic disable-next-line: no-unknown ---@diagnostic disable-next-line: no-unknown
package.loaded[modname] = nil package.loaded[modname] = nil
Util.try(function() Util.try(function()
local mod, err = modspec.load() local mod = type(modspec) == "function" and modspec() or require(modspec)
if err then if type(mod) ~= "table" then
self:error("Failed to load `" .. modname .. "`:\n" .. err) self.importing = nil
elseif type(mod) ~= "table" then
return self:error( return self:error(
"Invalid spec module: `" "Invalid spec module: `"
.. modname .. modname
@ -194,20 +175,21 @@ function Spec:import(spec)
.. type(mod) .. type(mod)
.. "` was returned instead" .. "` was returned instead"
) )
else
self:normalize(mod)
end end
self:normalize(mod)
self.importing = nil
Util.track()
end, { end, {
msg = "Failed to load `" .. modname .. "`", msg = "Failed to load `" .. modname .. "`",
on_error = function(msg) on_error = function(msg)
self:error(msg) self:error(msg)
self.importing = nil
Util.track()
end, end,
}) })
self.importing = nil
Util.track()
end end
if imported == 0 then if imported == 0 then
self:error("No specs found for module " .. vim.inspect(spec.import)) self:error("No specs found for module " .. spec.import)
end end
end end
@ -241,15 +223,12 @@ function M.update_state()
or plugin.cmd or plugin.cmd
plugin.lazy = lazy and true or false plugin.lazy = lazy and true or false
end end
if plugin.virtual then if plugin.dir:find(Config.options.root, 1, true) == 1 then
plugin._.is_local = true
plugin._.installed = true -- local plugins are managed by the user
elseif plugin.dir:find(Config.options.root .. "/", 1, true) == 1 then
plugin._.installed = installed[plugin.name] ~= nil plugin._.installed = installed[plugin.name] ~= nil
installed[plugin.name] = nil installed[plugin.name] = nil
else else
plugin._.is_local = true plugin._.is_local = true
plugin._.installed = vim.fn.isdirectory(plugin.dir) == 1 plugin._.installed = true -- local plugins are managed by the user
end end
end end
@ -291,6 +270,15 @@ function M.update_rocks_state()
end end
end end
---@param path string
function M.local_spec(path)
local file = vim.secure.read(path)
if file then
return loadstring(file)()
end
return {}
end
---@return LazySpecImport? ---@return LazySpecImport?
function M.find_local_spec() function M.find_local_spec()
if not Config.options.local_spec then if not Config.options.local_spec then
@ -305,7 +293,7 @@ function M.find_local_spec()
import = function() import = function()
local data = vim.secure.read(file) local data = vim.secure.read(file)
if data then if data then
return loadstring(data, M.LOCAL_SPEC)() return loadstring(data)()
end end
return {} return {}
end, end,
@ -346,16 +334,16 @@ function M.load()
end end
-- add hererocks when enabled and needed -- add hererocks when enabled and needed
for _, plugin in pairs(Config.spec.plugins) do if Config.options.rocks.hererocks then
if plugin.build == "rockspec" then for _, plugin in pairs(Config.spec.plugins) do
if Config.hererocks() then if plugin.build == "rockspec" then
Config.spec.meta:add({ Config.spec.meta:add({
"luarocks/hererocks", "luarocks/hererocks",
build = "rockspec", build = "rockspec",
lazy = true, lazy = true,
}) })
break
end end
break
end end
end end

View File

@ -29,10 +29,6 @@ function M.track(data, time)
end end
end end
function M.exiting()
return vim.v.exiting ~= vim.NIL
end
---@generic T ---@generic T
---@param list T[] ---@param list T[]
---@param fn fun(v: T):boolean? ---@param fn fun(v: T):boolean?
@ -66,7 +62,7 @@ end
---@param name string ---@param name string
---@return string ---@return string
function M.normname(name) function M.normname(name)
local ret = name:lower():gsub("^n?vim%-", ""):gsub("%.n?vim$", ""):gsub("[%.%-]lua", ""):gsub("[^a-z]+", "") local ret = name:lower():gsub("^n?vim%-", ""):gsub("%.n?vim$", ""):gsub("%.lua", ""):gsub("[^a-z]+", "")
return ret return ret
end end
@ -171,9 +167,7 @@ function M.very_lazy()
return return
end end
vim.g.did_very_lazy = true vim.g.did_very_lazy = true
M.track({ event = "VeryLazy" })
vim.api.nvim_exec_autocmds("User", { pattern = "VeryLazy", modeline = false }) vim.api.nvim_exec_autocmds("User", { pattern = "VeryLazy", modeline = false })
M.track()
end) end)
end end
@ -270,7 +264,7 @@ function M.get_unloaded_rtp(modname, opts)
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
if Config.spec then if Config.spec then
for _, plugin in pairs(Config.spec.plugins) do for _, plugin in pairs(Config.spec.plugins) do
if not (plugin._.loaded or plugin.module == false or plugin.virtual) then if not (plugin._.loaded or plugin.module == false) then
if norm == M.normname(plugin.name) then if norm == M.normname(plugin.name) then
table.insert(rtp, 1, plugin.dir) table.insert(rtp, 1, plugin.dir)
else else
@ -289,7 +283,7 @@ function M.find_root(modname)
local ret = require("lazy.core.cache").find(modname, { local ret = require("lazy.core.cache").find(modname, {
rtp = true, rtp = true,
paths = paths, paths = paths,
patterns = { ".lua", "" }, patterns = { "", ".lua" },
})[1] })[1]
if not ret and cached then if not ret and cached then
@ -297,27 +291,25 @@ function M.find_root(modname)
ret = require("lazy.core.cache").find(modname, { ret = require("lazy.core.cache").find(modname, {
rtp = false, rtp = false,
paths = paths, paths = paths,
patterns = { ".lua", "" }, patterns = { "", ".lua" },
})[1] })[1]
end end
if ret then if ret then
return ret.modpath:gsub("%.lua$", ""), ret.modpath local root = ret.modpath:gsub("/init%.lua$", ""):gsub("%.lua$", "")
return root
end end
end end
---@param modname string ---@param modname string
---@param fn fun(modname:string, modpath:string) ---@param fn fun(modname:string, modpath:string)
function M.lsmod(modname, fn) function M.lsmod(modname, fn)
local root, match = M.find_root(modname) local root = M.find_root(modname)
if not root then if not root then
return return
end end
if match:sub(-4) == ".lua" then if vim.uv.fs_stat(root .. ".lua") then
fn(modname, match) fn(modname, root .. ".lua")
if not vim.uv.fs_stat(root) then
return
end
end end
M.ls(root, function(path, name, type) M.ls(root, function(path, name, type)
@ -374,7 +366,6 @@ function M.notify(msg, opts)
local lang = opts.lang or "markdown" local lang = opts.lang or "markdown"
local n = opts.once and vim.notify_once or vim.notify local n = opts.once and vim.notify_once or vim.notify
n(msg, opts.level or vim.log.levels.INFO, { n(msg, opts.level or vim.log.levels.INFO, {
ft = lang,
on_open = function(win) on_open = function(win)
local ok = pcall(function() local ok = pcall(function()
vim.treesitter.language.add("markdown") vim.treesitter.language.add("markdown")

View File

@ -61,11 +61,7 @@ end
---@return string ---@return string
function M.extract(file, pattern) function M.extract(file, pattern)
local init = Util.read_file(file) local init = Util.read_file(file)
local ret = assert(init:match(pattern)) --[[@as string]] return assert(init:match(pattern))
local lines = vim.tbl_filter(function(line)
return not line:find("^%s*%-%-%s*stylua%s*:%s*ignore%s*$")
end, vim.split(ret, "\n"))
return table.concat(lines, "\n")
end end
---@return ReadmeBlock ---@return ReadmeBlock
@ -135,8 +131,7 @@ function M.colors(opts)
{ "---", "---", "---" }, { "---", "---", "---" },
} }
Util.foreach(require(opts.modname).colors, function(group, link) Util.foreach(require(opts.modname).colors, function(group, link)
link = type(link) == "table" and "`" .. vim.inspect(link):gsub("%s+", " ") .. "`" or "***" .. link .. "***" lines[#lines + 1] = { "**" .. opts.name .. group .. "**", "***" .. link .. "***", comments[group] or "" }
lines[#lines + 1] = { "**" .. opts.name .. group .. "**", link, comments[group] or "" }
end) end)
return { content = M.table(lines) } return { content = M.table(lines) }
end end

View File

@ -1,5 +1,4 @@
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Process = require("lazy.manage.process")
local uv = vim.uv or vim.loop local uv = vim.uv or vim.loop
local M = {} local M = {}
@ -37,18 +36,14 @@ function M.have(cmd, opts)
local found local found
for _, c in ipairs(cmd) do for _, c in ipairs(cmd) do
if vim.fn.executable(c) == 1 then if vim.fn.executable(c) == 1 then
local out, exit_code = Process.exec({ c, opts.version }) local version = vim.fn.system(c .. " " .. opts.version) or ""
if exit_code ~= 0 then version = vim.trim(vim.split(version, "\n")[1])
opts.error(("failed to get version of {%s}\n%s"):format(c, table.concat(out, "\n"))) version = version:gsub("^%s*" .. vim.pesc(c) .. "%s*", "")
if opts.version_pattern and not version:find(opts.version_pattern, 1, true) then
opts.warn(("`%s` version `%s` needed, but found `%s`"):format(c, opts.version_pattern, version))
else else
local version = vim.trim(out[1] or "") found = ("{%s} `%s`"):format(c, version)
version = version:gsub("^%s*" .. vim.pesc(c) .. "%s*", "") break
if opts.version_pattern and not version:find(opts.version_pattern, 1, true) then
opts.warn(("`%s` version `%s` needed, but found `%s`"):format(c, opts.version_pattern, version))
else
found = ("{%s} `%s`"):format(c, version)
break
end
end end
end end
end end
@ -130,7 +125,7 @@ function M.check()
start("luarocks") start("luarocks")
if Config.options.rocks.enabled then if Config.options.rocks.enabled then
if Config.hererocks() then if Config.options.rocks.hererocks then
info("checking `hererocks` installation") info("checking `hererocks` installation")
else else
info("checking `luarocks` installation") info("checking `luarocks` installation")
@ -160,7 +155,7 @@ function M.check()
"Lazy won't be able to install plugins that require `luarocks`.", "Lazy won't be able to install plugins that require `luarocks`.",
"Here's what you can do:", "Here's what you can do:",
" - fix your `luarocks` installation", " - fix your `luarocks` installation",
Config.hererocks() and " - disable *hererocks* with `opts.rocks.hererocks = false`" Config.options.rocks.hererocks and " - disable *hererocks* with `opts.rocks.hererocks = false`"
or " - enable `hererocks` with `opts.rocks.hererocks = true`", or " - enable `hererocks` with `opts.rocks.hererocks = true`",
" - disable `luarocks` support completely with `opts.rocks.enabled = false`", " - disable `luarocks` support completely with `opts.rocks.enabled = false`",
}, "\n")) }, "\n"))

View File

@ -35,9 +35,7 @@ end
function M.fast_check(opts) function M.fast_check(opts)
opts = opts or {} opts = opts or {}
for _, plugin in pairs(Config.plugins) do for _, plugin in pairs(Config.plugins) do
-- don't check local plugins here, since we mark them as needing updates if not plugin.pin and not plugin.dev and plugin._.installed then
-- only if local is behind upstream (if the git log task gives no output)
if plugin._.installed and not (plugin.pin or plugin._.is_local) then
plugin._.updates = nil plugin._.updates = nil
local info = Git.info(plugin.dir) local info = Git.info(plugin.dir)
local ok, target = pcall(Git.get_target, plugin) local ok, target = pcall(Git.get_target, plugin)

View File

@ -116,12 +116,6 @@ end
---@param plugin LazyPlugin ---@param plugin LazyPlugin
---@return GitInfo? ---@return GitInfo?
function M.get_target(plugin) function M.get_target(plugin)
if plugin._.is_local then
local info = M.info(plugin.dir)
local branch = assert(info and info.branch or M.get_branch(plugin))
return { branch = branch, commit = M.get_commit(plugin.dir, branch, true) }
end
local branch = assert(M.get_branch(plugin)) local branch = assert(M.get_branch(plugin))
if plugin.commit then if plugin.commit then
@ -150,6 +144,7 @@ function M.get_target(plugin)
} }
end end
end end
---@diagnostic disable-next-line: return-type-mismatch
return { branch = branch, commit = M.get_commit(plugin.dir, branch, true) } return { branch = branch, commit = M.get_commit(plugin.dir, branch, true) }
end end

View File

@ -80,7 +80,6 @@ function M.install(opts)
opts = M.opts(opts, { mode = "install" }) opts = M.opts(opts, { mode = "install" })
return M.run({ return M.run({
pipeline = { pipeline = {
"plugin.exists",
"git.clone", "git.clone",
{ "git.checkout", lockfile = opts.lockfile }, { "git.checkout", lockfile = opts.lockfile },
"plugin.docs", "plugin.docs",
@ -109,7 +108,6 @@ function M.update(opts)
opts = M.opts(opts, { mode = "update" }) opts = M.opts(opts, { mode = "update" })
return M.run({ return M.run({
pipeline = { pipeline = {
"plugin.exists",
"git.origin", "git.origin",
"git.branch", "git.branch",
"git.fetch", "git.fetch",
@ -149,7 +147,6 @@ function M.check(opts)
opts = opts or {} opts = opts or {}
return M.run({ return M.run({
pipeline = { pipeline = {
"plugin.exists",
{ "git.origin", check = true }, { "git.origin", check = true },
"git.fetch", "git.fetch",
"git.status", "git.status",

View File

@ -3,53 +3,50 @@ local Git = require("lazy.manage.git")
local M = {} local M = {}
---@alias LazyLockfile table<string, {commit:string, branch:string}> ---@type table<string, {commit:string, branch:string}>
---@type LazyLockfile
M.lock = {} M.lock = {}
M._loaded = false M._loaded = false
function M.update() function M.update()
M.load()
vim.fn.mkdir(vim.fn.fnamemodify(Config.options.lockfile, ":p:h"), "p") vim.fn.mkdir(vim.fn.fnamemodify(Config.options.lockfile, ":p:h"), "p")
local f = assert(io.open(Config.options.lockfile, "wb")) local f = assert(io.open(Config.options.lockfile, "wb"))
f:write("{\n") f:write("{\n")
M.lock = {}
-- keep disabled and cond plugins ---@param plugin LazyPlugin
for name in pairs(M.lock) do local plugins = vim.tbl_filter(function(plugin)
if not (Config.spec.disabled[name] or Config.spec.ignore_installed[name]) then return not plugin._.is_local and plugin._.installed
M.lock[name] = nil end, Config.plugins)
end
end
for _, plugin in pairs(Config.plugins) do
if not plugin._.is_local and plugin._.installed then
local info = assert(Git.info(plugin.dir))
M.lock[plugin.name] = {
branch = info.branch or assert(Git.get_branch(plugin)),
commit = assert(info.commit, "commit is nil"),
}
end
end
---@param plugin LazyPlugin
---@type string[] ---@type string[]
local names = vim.tbl_keys(M.lock) local names = vim.tbl_map(function(plugin)
return plugin.name
end, plugins)
table.sort(names) table.sort(names)
for n, name in ipairs(names) do for n, name in ipairs(names) do
local info = M.lock[name] local plugin = Config.plugins[name]
f:write(([[ %q: { "branch": %q, "commit": %q }]]):format(name, info.branch, info.commit)) if not plugin._.is_local and plugin._.installed then
if n ~= #names then local info = assert(Git.info(plugin.dir))
f:write(",\n") if not info.branch then
info.branch = assert(Git.get_branch(plugin))
end
info.commit = info.commit
-- f:write(([[ [%q] = { branch = %q, commit = %q },]]):format(name, info.branch, info.commit) .. "\n")
f:write(([[ %q: { "branch": %q, "commit": %q }]]):format(name, info.branch, info.commit))
if n ~= #names then
f:write(",\n")
end
---@diagnostic disable-next-line: assign-type-mismatch
M.lock[plugin.name] = info
end end
end end
f:write("\n}\n") f:write("\n}")
f:close() f:close()
end end
function M.load() function M.load()
if M._loaded then
return
end
M.lock = {} M.lock = {}
M._loaded = true M._loaded = true
local f = io.open(Config.options.lockfile, "r") local f = io.open(Config.options.lockfile, "r")
@ -67,7 +64,9 @@ end
---@param plugin LazyPlugin ---@param plugin LazyPlugin
---@return {commit:string, branch:string} ---@return {commit:string, branch:string}
function M.get(plugin) function M.get(plugin)
M.load() if not M._loaded then
M.load()
end
return M.lock[plugin.name] return M.lock[plugin.name]
end end

View File

@ -42,8 +42,8 @@ function Process.new(cmd, opts)
opts = opts or {} opts = opts or {}
opts.args = opts.args or {} opts.args = opts.args or {}
if type(cmd) == "table" then if type(cmd) == "table" then
self.cmd = cmd[1] self.cmd = table.remove(cmd, 1)
vim.list_extend(opts.args, vim.list_slice(cmd, 2)) vim.list_extend(opts.args, cmd)
else else
self.cmd = cmd self.cmd = cmd
end end
@ -93,7 +93,7 @@ function Process:_run()
end) end)
self:suspend() self:suspend()
while not (self.handle:is_closing() and stdout:is_closing() and stderr:is_closing()) do while not (self.handle:is_closing() and stdout:is_closing() and stderr:is_closing()) do
Async.yield() coroutine.yield()
end end
else else
self.data = "Failed to spawn process " .. self.cmd .. " " .. vim.inspect(self.opts) self.data = "Failed to spawn process " .. self.cmd .. " " .. vim.inspect(self.opts)
@ -233,7 +233,10 @@ function M.exec(cmd, opts)
opts = opts or {} opts = opts or {}
local proc = M.spawn(cmd, opts) local proc = M.spawn(cmd, opts)
proc:wait() proc:wait()
return vim.split(proc.data, "\n"), proc.code if proc.code ~= 0 then
error("Process failed with code " .. proc.code)
end
return vim.split(proc.data, "\n")
end end
return M return M

View File

@ -78,7 +78,6 @@ function Runner:_start()
---@type number? ---@type number?
local wait_step = nil local wait_step = nil
---@async
---@param resume? boolean ---@param resume? boolean
local function continue(resume) local function continue(resume)
active = 0 active = 0
@ -115,30 +114,22 @@ function Runner:_start()
end end
local s = state[name] local s = state[name]
local plugin = self:plugin(name) local plugin = self:plugin(name)
while s.step <= #self._pipeline do if s.step == #self._pipeline then
if s.step == #self._pipeline then -- done
-- done s.task = nil
s.task = nil plugin._.working = false
elseif s.step < #self._pipeline then
-- next
s.step = s.step + 1
local step = self._pipeline[s.step]
if step.task == "wait" then
plugin._.working = false plugin._.working = false
break waiting = waiting + 1
elseif s.step < #self._pipeline then wait_step = s.step
-- next else
s.step = s.step + 1 s.task = self:queue(plugin, step)
local step = self._pipeline[s.step] plugin._.working = true
if step.task == "wait" then active = active + 1
plugin._.working = false
waiting = waiting + 1
wait_step = s.step
break
else
s.task = self:queue(plugin, step)
plugin._.working = true
if s.task then
active = active + 1
s.task:wake(false)
break
end
end
end end
end end
end end
@ -153,9 +144,7 @@ function Runner:_start()
end end
continue(true) continue(true)
end end
if active > 0 then coroutine.yield()
self._running:suspend()
end
end end
end end

View File

@ -21,23 +21,16 @@ M.clean = {
skip = function(plugin) skip = function(plugin)
return plugin._.is_local return plugin._.is_local
end, end,
---@param opts? {rocks_only?:boolean} run = function(self)
run = function(self, opts)
opts = opts or {}
local dir = self.plugin.dir:gsub("/+$", "") local dir = self.plugin.dir:gsub("/+$", "")
assert(dir:find(Config.options.root .. "/", 1, true) == 1, self.plugin.dir .. " should be under packpath!") assert(dir:find(Config.options.root, 1, true) == 1, self.plugin.dir .. " should be under packpath!")
rm(dir)
local rock_root = Config.options.rocks.root .. "/" .. self.plugin.name local rock_root = Config.options.rocks.root .. "/" .. self.plugin.name
if vim.uv.fs_stat(rock_root) then if vim.uv.fs_stat(rock_root) then
rm(rock_root) rm(rock_root)
end end
if opts.rocks_only then
return
end
rm(dir)
self.plugin._.installed = false self.plugin._.installed = false
end, end,
} }

View File

@ -1,54 +1,8 @@
local Async = require("lazy.async")
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Git = require("lazy.manage.git") local Git = require("lazy.manage.git")
local Lock = require("lazy.manage.lock") local Lock = require("lazy.manage.lock")
local Util = require("lazy.util") local Util = require("lazy.util")
local throttle = {}
throttle.running = 0
throttle.waiting = {} ---@type Async[]
throttle.timer = vim.uv.new_timer()
function throttle.next()
throttle.running = 0
while #throttle.waiting > 0 and throttle.running < Config.options.git.throttle.rate do
---@type Async
local task = table.remove(throttle.waiting, 1)
task:resume()
throttle.running = throttle.running + 1
end
if throttle.running == 0 then
throttle.timer:stop()
end
end
function throttle.wait()
if not Config.options.git.throttle.enabled then
return
end
if not throttle.timer:is_active() then
throttle.timer:start(0, Config.options.git.throttle.duration, vim.schedule_wrap(throttle.next))
end
local running = Async.running()
if throttle.running < Config.options.git.throttle.rate then
throttle.running = throttle.running + 1
else
table.insert(throttle.waiting, running)
coroutine.yield("waiting")
running:suspend()
coroutine.yield("")
end
end
---@param plugin LazyPlugin
local function cooldown(plugin)
if not plugin._.last_check then
return false
end
local delta = (vim.uv.now() - plugin._.last_check) / 1000
return delta < Config.options.git.cooldown
end
---@type table<string, LazyTaskDef> ---@type table<string, LazyTaskDef>
local M = {} local M = {}
@ -67,7 +21,6 @@ M.log = {
---@async ---@async
---@param opts {args?: string[], updated?:boolean, check?:boolean} ---@param opts {args?: string[], updated?:boolean, check?:boolean}
run = function(self, opts) run = function(self, opts)
-- self:spawn({ "sleep", "5" })
local args = { local args = {
"log", "log",
"--pretty=format:%h %s (%cr)", "--pretty=format:%h %s (%cr)",
@ -78,13 +31,11 @@ M.log = {
"--no-show-signature", "--no-show-signature",
} }
local info, target
if opts.updated then if opts.updated then
table.insert(args, self.plugin._.updated.from .. ".." .. (self.plugin._.updated.to or "HEAD")) table.insert(args, self.plugin._.updated.from .. ".." .. (self.plugin._.updated.to or "HEAD"))
elseif opts.check then elseif opts.check then
info = assert(Git.info(self.plugin.dir)) local info = assert(Git.info(self.plugin.dir))
target = assert(Git.get_target(self.plugin)) local target = assert(Git.get_target(self.plugin))
if not target.commit then if not target.commit then
for k, v in pairs(target) do for k, v in pairs(target) do
error(k .. " '" .. v .. "' not found") error(k .. " '" .. v .. "' not found")
@ -92,17 +43,15 @@ M.log = {
error("no target commit found") error("no target commit found")
end end
assert(target.commit, self.plugin.name .. " " .. target.branch) assert(target.commit, self.plugin.name .. " " .. target.branch)
if not self.plugin._.is_local then if Git.eq(info, target) then
if Git.eq(info, target) then if Config.options.checker.check_pinned then
if Config.options.checker.check_pinned then local last_commit = Git.get_commit(self.plugin.dir, target.branch, true)
local last_commit = Git.get_commit(self.plugin.dir, target.branch, true) if not Git.eq(info, { commit = last_commit }) then
if not Git.eq(info, { commit = last_commit }) then self.plugin._.outdated = true
self.plugin._.outdated = true
end
end end
else
self.plugin._.updates = { from = info, to = target }
end end
else
self.plugin._.updates = { from = info, to = target }
end end
table.insert(args, info.commit .. ".." .. target.commit) table.insert(args, info.commit .. ".." .. target.commit)
else else
@ -113,14 +62,6 @@ M.log = {
args = args, args = args,
cwd = self.plugin.dir, cwd = self.plugin.dir,
}) })
-- for local plugins, mark as needing updates only if local is
-- behind upstream, i.e. if git log gave no output
if opts.check and self.plugin._.is_local then
if not vim.tbl_isempty(self:get_log()) then
self.plugin._.updates = { from = info, to = target }
end
end
end, end,
} }
@ -130,7 +71,6 @@ M.clone = {
end, end,
---@async ---@async
run = function(self) run = function(self)
throttle.wait()
local args = { local args = {
"clone", "clone",
self.plugin.url, self.plugin.url,
@ -275,12 +215,11 @@ M.status = {
-- fetches all needed origin branches -- fetches all needed origin branches
M.fetch = { M.fetch = {
skip = function(plugin) skip = function(plugin)
return not plugin._.installed or plugin._.is_local or cooldown(plugin) return not plugin._.installed or plugin._.is_local
end, end,
---@async ---@async
run = function(self) run = function(self)
throttle.wait()
local args = { local args = {
"fetch", "fetch",
"--recurse-submodules", "--recurse-submodules",
@ -296,11 +235,6 @@ M.fetch = {
self:spawn("git", { self:spawn("git", {
args = args, args = args,
cwd = self.plugin.dir, cwd = self.plugin.dir,
on_exit = function(ok)
if ok then
self.plugin._.last_check = vim.uv.now()
end
end,
}) })
end, end,
} }
@ -315,7 +249,6 @@ M.checkout = {
---@async ---@async
---@param opts {lockfile?:boolean} ---@param opts {lockfile?:boolean}
run = function(self, opts) run = function(self, opts)
throttle.wait()
local info = assert(Git.info(self.plugin.dir)) local info = assert(Git.info(self.plugin.dir))
local target = assert(Git.get_target(self.plugin)) local target = assert(Git.get_target(self.plugin))
@ -335,7 +268,7 @@ M.checkout = {
end end
end end
-- don't run checkout if target is already reached. -- dont run checkout if target is already reached.
-- unless we just cloned, since then we won't have any data yet -- unless we just cloned, since then we won't have any data yet
if Git.eq(info, target) and info.branch == target.branch then if Git.eq(info, target) and info.branch == target.branch then
self.plugin._.updated = { self.plugin._.updated = {

View File

@ -19,9 +19,6 @@ local B = {}
---@param task LazyTask ---@param task LazyTask
---@param build string ---@param build string
function B.cmd(task, build) function B.cmd(task, build)
if task.plugin.build ~= "rockspec" then
Loader.load(task.plugin, { task = "build" })
end
local cmd = vim.api.nvim_parse_cmd(build:sub(2), {}) --[[@as vim.api.keyset.cmd]] local cmd = vim.api.nvim_parse_cmd(build:sub(2), {}) --[[@as vim.api.keyset.cmd]]
task:log(vim.api.nvim_cmd(cmd, { output = true })) task:log(vim.api.nvim_cmd(cmd, { output = true }))
end end
@ -51,6 +48,10 @@ M.build = {
run = function(self) run = function(self)
vim.cmd([[silent! runtime plugin/rplugin.vim]]) vim.cmd([[silent! runtime plugin/rplugin.vim]])
if self.plugin.build ~= "rockspec" then
Loader.load(self.plugin, { task = "build" })
end
local builders = self.plugin.build local builders = self.plugin.build
-- Skip if `build` is set to `false` -- Skip if `build` is set to `false`
@ -87,25 +88,14 @@ M.build = {
M.docs = { M.docs = {
skip = function(plugin) skip = function(plugin)
return not plugin._.is_local and not plugin._.dirty return not plugin._.dirty
end, end,
run = function(self) run = function(self)
local docs = self.plugin.dir .. "/doc" local docs = self.plugin.dir .. "/doc/"
if Util.file_exists(docs) then if Util.file_exists(docs) then
self:log(vim.api.nvim_cmd({ cmd = "helptags", args = { docs } }, { output = true })) self:log(vim.api.nvim_cmd({ cmd = "helptags", args = { docs } }, { output = true }))
end end
end, end,
} }
M.exists = {
skip = function(plugin)
return not plugin._.is_local or plugin.virtual
end,
run = function(self)
if not Util.file_exists(self.plugin.dir) then
self:error("Local plugin does not exist at `" .. self.plugin.dir .. "`")
end
end,
}
return M return M

View File

@ -20,39 +20,11 @@ function M.extend(defaults, opts)
return vim.tbl_deep_extend("force", defaults, opts, { spec = spec }) return vim.tbl_deep_extend("force", defaults, opts, { spec = spec })
end end
---@param opts LazyConfig
function M.setup(opts) function M.setup(opts)
opts = M.extend({ opts = M.extend({
local_spec = false,
change_detection = { enabled = false }, change_detection = { enabled = false },
dev = {
patterns = vim.env.LAZY_DEV and vim.split(vim.env.LAZY_DEV, ",") or nil,
},
}, opts) }, opts)
local args = {}
local is_busted = false
local is_minitest = false
local offline = vim.env.LAZY_OFFLINE == "1" or vim.env.LAZY_OFFLINE == "true"
for _, a in ipairs(_G.arg) do
if a == "--busted" then
is_busted = true
elseif a == "--minitest" then
is_minitest = true
elseif a == "--offline" then
offline = true
else
table.insert(args, a)
end
end
_G.arg = args
if is_busted then
opts = M.busted.setup(opts)
elseif is_minitest then
opts = M.minitest.setup(opts)
end
-- set stdpaths to use .tests -- set stdpaths to use .tests
if vim.env.LAZY_STDPATH then if vim.env.LAZY_STDPATH then
local root = vim.fn.fnamemodify(vim.env.LAZY_STDPATH, ":p") local root = vim.fn.fnamemodify(vim.env.LAZY_STDPATH, ":p")
@ -60,14 +32,13 @@ function M.setup(opts)
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end end
end end
vim.o.loadplugins = true vim.o.loadplugins = true
require("lazy").setup(opts) require("lazy").setup(opts)
if vim.g.colors_name == nil then if vim.g.colors_name == nil then
vim.cmd("colorscheme habamax") vim.cmd("colorscheme habamax")
end end
if not offline then require("lazy").update():wait()
require("lazy").update():wait()
end
if vim.bo.filetype == "lazy" then if vim.bo.filetype == "lazy" then
local errors = false local errors = false
for _, plugin in pairs(require("lazy.core.config").spec.plugins) do for _, plugin in pairs(require("lazy.core.config").spec.plugins) do
@ -77,12 +48,6 @@ function M.setup(opts)
vim.cmd.close() vim.cmd.close()
end end
end end
if is_busted then
M.busted.run()
elseif is_minitest then
M.minitest.run()
end
end end
function M.repro(opts) function M.repro(opts)
@ -103,73 +68,18 @@ function M.repro(opts)
M.setup(opts) M.setup(opts)
end end
M.minitest = {}
function M.minitest.run()
local Config = require("lazy.core.config")
-- disable termnial output for the tests
Config.options.headless = {}
if not require("lazy.core.config").headless() then
return vim.notify("busted can only run in headless mode. Please run with `nvim -l`", vim.log.levels.WARN)
end
package.path = package.path .. ";" .. vim.uv.cwd() .. "/tests/?.lua"
local Test = require("mini.test")
local expect = Test.expect
local _assert = assert
local Assert = {
__call = function(_, ...)
return _assert(...)
end,
same = expect.equality,
equal = expect.equality,
are = {
equal = expect.equality,
},
is_not = {
same = expect.no_equality,
},
is_not_nil = function(a)
return expect.no_equality(nil, a)
end,
is_true = function(a)
return expect.equality(true, a)
end,
is_false = function(a)
return expect.equality(false, a)
end,
}
Assert.__index = Assert
assert = setmetatable({}, Assert)
assert = require("luassert")
require("mini.test").run()
end
---@param opts LazyConfig ---@param opts LazyConfig
function M.minitest.setup(opts) function M.busted(opts)
return M.extend({ opts = M.extend({
spec = { spec = {
"lunarmodules/luassert", "lunarmodules/busted",
{ { dir = vim.fn.fnamemodify(".", ":p") },
"echasnovski/mini.test",
opts = {
collect = {
find_files = function()
return #_G.arg > 0 and _G.arg or vim.fn.globpath("tests", "**/*_spec.lua", true, true)
end,
},
-- script_path = "tests/minit.lua",
},
},
{ dir = vim.uv.cwd() },
}, },
rocks = { hererocks = true }, rocks = { hererocks = true },
}, opts) }, opts)
end
M.busted = {} M.setup(opts)
function M.busted.run()
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
-- disable termnial output for the tests -- disable termnial output for the tests
Config.options.headless = {} Config.options.headless = {}
@ -177,43 +87,10 @@ function M.busted.run()
if not require("lazy.core.config").headless() then if not require("lazy.core.config").headless() then
return vim.notify("busted can only run in headless mode. Please run with `nvim -l`", vim.log.levels.WARN) return vim.notify("busted can only run in headless mode. Please run with `nvim -l`", vim.log.levels.WARN)
end end
package.path = package.path .. ";" .. vim.uv.cwd() .. "/tests/?.lua"
-- run busted -- run busted
return pcall(require("busted.runner"), { return pcall(require("busted.runner"), {
standalone = false, standalone = false,
}) or os.exit(1) }) or os.exit(1)
end end
---@param opts LazyConfig
function M.busted.setup(opts)
local args = table.concat(_G.arg, " ")
local json = args:find("--output[ =]json")
return M.extend({
spec = {
"lunarmodules/busted",
{ dir = vim.uv.cwd() },
},
headless = {
process = not json,
log = not json,
task = not json,
},
rocks = { hererocks = true },
}, opts)
end
---@param opts LazyConfig
function M.busted.init(opts)
opts = M.busted.setup(opts)
M.setup(opts)
M.busted.run()
end
setmetatable(M.busted, {
__call = function(_, opts)
M.busted.init(opts)
end,
})
return M return M

View File

@ -63,9 +63,6 @@ function M.update()
pkg.spec = { _raw = spec.code } pkg.spec = { _raw = spec.code }
end end
table.insert(ret.pkgs, pkg) table.insert(ret.pkgs, pkg)
if not plugin._.pkg and plugin._.loaded and pkg.source == "rockspec" then
require("lazy.core.loader").add_to_luapath(plugin)
end
break break
end end
end end

View File

@ -72,29 +72,31 @@ function M.check(opts)
}, opts or {}) }, opts or {})
local ok = false local ok = false
if Config.hererocks() then if Config.options.rocks.hererocks then
if M.hererocks.building() then if M.hererocks.building() then
ok = true ok = true
else else
ok = Health.have(M.python, opts) ok = Health.have(M.python, opts)
ok = Health.have(M.hererocks.bin("luarocks")) and ok ok = Health.have(M.hererocks.bin("luarocks")) and ok
Health.have( ok = Health.have(
M.hererocks.bin("lua"), M.hererocks.bin("lua"),
vim.tbl_extend("force", opts, { vim.tbl_extend("force", opts, {
version = "-v", version = "-v",
version_pattern = "5.1", version_pattern = "5.1",
}) })
) ) and ok
end end
else else
ok = Health.have("luarocks", opts) ok = Health.have("luarocks", opts)
Health.have( ok = (
{ "lua5.1", "lua", "lua-5.1" }, Health.have(
vim.tbl_extend("force", opts, { { "lua5.1", "lua", "lua-5.1" },
version = "-v", vim.tbl_extend("force", opts, {
version_pattern = "5.1", version = "-v",
}) version_pattern = "5.1",
) })
)
) and ok
end end
return ok return ok
end end
@ -102,30 +104,26 @@ end
---@async ---@async
---@param task LazyTask ---@param task LazyTask
function M.build(task) function M.build(task)
M.check({ if
error = function(msg) not M.check({
task:error(msg:gsub("[{}]", "`")) error = function(msg)
end, task:error(msg:gsub("[{}]", "`"))
warn = function(msg) end,
task:warn(msg) warn = function(msg)
end, task:warn(msg)
ok = function(msg) end, end,
}) ok = function(msg) end,
})
if task:has_warnings() then then
task:log({ task:log({
"", "",
"This plugin requires `luarocks`. Try one of the following:", "This plugin requires `luarocks`. Try one of the following:",
" - fix your `luarocks` installation", " - fix your `luarocks` installation",
Config.hererocks() and " - disable *hererocks* with `opts.rocks.hererocks = false`" Config.options.rocks.hererocks and " - disable *hererocks* with `opts.rocks.hererocks = false`"
or " - enable `hererocks` with `opts.rocks.hererocks = true`", or " - enable `hererocks` with `opts.rocks.hererocks = true`",
" - disable `luarocks` support completely with `opts.rocks.enabled = false`", " - disable `luarocks` support completely with `opts.rocks.enabled = false`",
}) })
task:warn("\nWill try building anyway, but will likely fail...") return
task:warn("\n" .. string.rep("-", 80) .. "\n")
task:set_level(vim.log.levels.WARN)
end end
if task.plugin.name == "hererocks" then if task.plugin.name == "hererocks" then
@ -134,7 +132,7 @@ function M.build(task)
local env = {} local env = {}
local luarocks = "luarocks" local luarocks = "luarocks"
if Config.hererocks() then if Config.options.rocks.hererocks then
-- hererocks is still building, so skip for now -- hererocks is still building, so skip for now
-- a new build will happen in the next round -- a new build will happen in the next round
if M.hererocks.building() then if M.hererocks.building() then
@ -172,6 +170,7 @@ function M.build(task)
root, root,
"--server", "--server",
Config.options.rocks.server, Config.options.rocks.server,
"--dev",
"--lua-version", "--lua-version",
"5.1", "5.1",
"install", -- use install so that we can make use of pre-built rocks "install", -- use install so that we can make use of pre-built rocks
@ -188,13 +187,11 @@ function M.build(task)
return return
end end
task:warn("Failed installing " .. rockspec.package .. " with `luarocks`.") task:warn("Failed installing " .. rockspec.package .. " with `luarocks`.\nTrying to build from source.")
task:warn("\n" .. string.rep("-", 80) .. "\n")
task:warn("Trying to build from source.")
-- install failed, so try building from source -- install failed, so try building from source
task:set_level() -- reset level task:set_level() -- reset level
ok = task:spawn(luarocks, { task:spawn(luarocks, {
args = { args = {
"--tree", "--tree",
root, root,
@ -209,9 +206,6 @@ function M.build(task)
cwd = task.plugin.dir, cwd = task.plugin.dir,
env = env, env = env,
}) })
if not ok then
require("lazy.manage.task.fs").clean.run(task, { rocks_only = true })
end
end end
---@param rockspec RockSpec ---@param rockspec RockSpec
@ -224,10 +218,9 @@ end
---@return table? ---@return table?
function M.parse(file) function M.parse(file)
local ret = {} local ret = {}
local ok = pcall(function() return pcall(function()
loadfile(file, nil, ret)() loadfile(file, "t", ret)()
end) and ret or nil end) and ret or nil
return ok and ret or nil
end end
---@param plugin LazyPlugin ---@param plugin LazyPlugin
@ -285,10 +278,7 @@ function M.get(plugin)
---@param dep string ---@param dep string
local rocks = vim.tbl_filter(function(dep) local rocks = vim.tbl_filter(function(dep)
local name = dep:match("^%s*([^~><=%s]+)") local name = dep:gsub("%s.*", "")
if not name then
return false
end
local url = Community.get_url(name) local url = Community.get_url(name)
local spec = Community.get_spec(name) local spec = Community.get_spec(name)

View File

@ -21,7 +21,6 @@ M.C = nil
function M.on_ui_enter() function M.on_ui_enter()
M._stats.startuptime = M.track("UIEnter") M._stats.startuptime = M.track("UIEnter")
require("lazy.core.util").track({ start = "startuptime" }, M._stats.startuptime * 1e6)
vim.api.nvim_exec_autocmds("User", { pattern = "LazyVimStarted", modeline = false }) vim.api.nvim_exec_autocmds("User", { pattern = "LazyVimStarted", modeline = false })
end end
@ -35,10 +34,11 @@ function M.cputime()
if M.C == nil then if M.C == nil then
pcall(function() pcall(function()
ffi.cdef([[ ffi.cdef([[
typedef long time_t;
typedef int clockid_t; typedef int clockid_t;
typedef struct timespec { typedef struct timespec {
int64_t tv_sec; /* Use fixed 64-bit type for portability */ time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */ long tv_nsec; /* nanoseconds */
} nanotime; } nanotime;
int clock_gettime(clockid_t clk_id, struct timespec *tp); int clock_gettime(clockid_t clk_id, struct timespec *tp);
]]) ]])
@ -47,8 +47,7 @@ function M.cputime()
end end
local function real() local function real()
-- Zero-initialize to handle 32-bit systems where only lower 32 bits are written local pnano = assert(ffi.new("nanotime[?]", 1))
local pnano = ffi.new("nanotime[1]")
local CLOCK_PROCESS_CPUTIME_ID = jit.os == "OSX" and 12 or 2 local CLOCK_PROCESS_CPUTIME_ID = jit.os == "OSX" and 12 or 2
ffi.C.clock_gettime(CLOCK_PROCESS_CPUTIME_ID, pnano) ffi.C.clock_gettime(CLOCK_PROCESS_CPUTIME_ID, pnano)
return tonumber(pnano[0].tv_sec) * 1e3 + tonumber(pnano[0].tv_nsec) / 1e6 return tonumber(pnano[0].tv_sec) * 1e3 + tonumber(pnano[0].tv_nsec) / 1e6

View File

@ -10,7 +10,6 @@
---@field dirty? boolean ---@field dirty? boolean
---@field build? boolean ---@field build? boolean
---@field frags? number[] ---@field frags? number[]
---@field top? boolean
---@field handlers? LazyPluginHandlers ---@field handlers? LazyPluginHandlers
---@field installed? boolean ---@field installed? boolean
---@field is_local? boolean ---@field is_local? boolean
@ -21,7 +20,6 @@
---@field tasks? LazyTask[] ---@field tasks? LazyTask[]
---@field updated? {from:string, to:string} ---@field updated? {from:string, to:string}
---@field updates? {from:GitInfo, to:GitInfo} ---@field updates? {from:GitInfo, to:GitInfo}
---@field last_check? number
---@field working? boolean ---@field working? boolean
---@field pkg? LazyPkg ---@field pkg? LazyPkg
@ -61,7 +59,6 @@
---@field priority? number Only useful for lazy=false plugins to force loading certain plugins first. Default priority is 50 ---@field priority? number Only useful for lazy=false plugins to force loading certain plugins first. Default priority is 50
---@field dev? boolean If set, then link to the respective folder under your ~/projects ---@field dev? boolean If set, then link to the respective folder under your ~/projects
---@field rocks? string[] ---@field rocks? string[]
---@field virtual? boolean virtual plugins won't be installed or added to the rtp.
---@class LazyPlugin: LazyPluginBase,LazyPluginHandlers,LazyPluginHooks,LazyPluginRef ---@class LazyPlugin: LazyPluginBase,LazyPluginHandlers,LazyPluginHooks,LazyPluginRef
---@field dependencies? string[] ---@field dependencies? string[]
@ -76,8 +73,6 @@
---@field module? false ---@field module? false
---@class LazyPluginSpec: LazyPluginBase,LazyPluginSpecHandlers,LazyPluginHooks,LazyPluginRef ---@class LazyPluginSpec: LazyPluginBase,LazyPluginSpecHandlers,LazyPluginHooks,LazyPluginRef
---@field name? string display name and name used for plugin config files
---@field dir? string
---@field dependencies? string|string[]|LazyPluginSpec[] ---@field dependencies? string|string[]|LazyPluginSpec[]
---@field specs? string|string[]|LazyPluginSpec[] ---@field specs? string|string[]|LazyPluginSpec[]

View File

@ -162,21 +162,12 @@ end
---@param opts? LazyCmdOptions|{filetype?:string} ---@param opts? LazyCmdOptions|{filetype?:string}
function M.float_cmd(cmd, opts) function M.float_cmd(cmd, opts)
opts = opts or {} opts = opts or {}
local Process = require("lazy.manage.process")
local lines, code = Process.exec(cmd, { cwd = opts.cwd })
if code ~= 0 then
M.error({
"`" .. table.concat(cmd, " ") .. "`",
"",
"## Error",
table.concat(lines, "\n"),
}, { title = "Command Failed (" .. code .. ")" })
return
end
local float = M.float(opts) local float = M.float(opts)
if opts.filetype then if opts.filetype then
vim.bo[float.buf].filetype = opts.filetype vim.bo[float.buf].filetype = opts.filetype
end end
local Process = require("lazy.manage.process")
local lines = Process.exec(cmd, { cwd = opts.cwd })
vim.api.nvim_buf_set_lines(float.buf, 0, -1, false, lines) vim.api.nvim_buf_set_lines(float.buf, 0, -1, false, lines)
vim.bo[float.buf].modifiable = false vim.bo[float.buf].modifiable = false
return float return float

View File

@ -146,7 +146,7 @@ end
---@return string, string[] ---@return string, string[]
function M.parse(args) function M.parse(args)
local parts = vim.split(vim.trim(args), "%s+") local parts = vim.split(vim.trim(args), "%s+")
if vim.startswith("Lazy", parts[1]) then if parts[1]:find("Lazy") then
table.remove(parts, 1) table.remove(parts, 1)
end end
if args:sub(-1) == " " then if args:sub(-1) == " " then

View File

@ -34,8 +34,6 @@ M.keys = {
profile_sort = "<C-s>", profile_sort = "<C-s>",
profile_filter = "<C-f>", profile_filter = "<C-f>",
abort = "<C-c>", abort = "<C-c>",
next = "]]",
prev = "[[",
} }
---@type table<string,LazyViewCommand> ---@type table<string,LazyViewCommand>

View File

@ -166,7 +166,7 @@ function M:mount()
self:augroup(true) self:augroup(true)
end, { win = true }) end, { win = true })
self:focus() self:focus()
self:on_key(ViewConfig.keys.close, self.close, "Close") self:on_key(ViewConfig.keys.close, self.close)
self:on({ "BufDelete", "BufHidden" }, self.close) self:on({ "BufDelete", "BufHidden" }, self.close)
if vim.bo[self.buf].buftype == "" then if vim.bo[self.buf].buftype == "" then
@ -252,7 +252,7 @@ end
---@param fn fun(self?) ---@param fn fun(self?)
---@param desc? string ---@param desc? string
---@param mode? string[] ---@param mode? string[]
function M:on_key(key, fn, desc, mode) function M:on_key(key, fn, desc,mode)
vim.keymap.set(mode or "n", key, function() vim.keymap.set(mode or "n", key, function()
fn(self) fn(self)
end, { end, {
@ -295,7 +295,6 @@ function M:close(opts)
vim.diagnostic.reset(Config.ns, buf) vim.diagnostic.reset(Config.ns, buf)
vim.api.nvim_buf_delete(buf, { force = true }) vim.api.nvim_buf_delete(buf, { force = true })
end end
vim.cmd.redraw()
end) end)
end end

View File

@ -83,9 +83,8 @@ function M.create()
vim.keymap.set("n", ViewConfig.keys.abort, function() vim.keymap.set("n", ViewConfig.keys.abort, function()
require("lazy.manage.process").abort() require("lazy.manage.process").abort()
require("lazy.async").abort()
return ViewConfig.keys.abort return ViewConfig.keys.abort
end, { silent = true, buffer = self.buf, expr = true, desc = "Abort" }) end, { silent = true, buffer = self.buf, expr = true })
vim.keymap.set("n", "gx", "K", { buffer = self.buf, remap = true }) vim.keymap.set("n", "gx", "K", { buffer = self.buf, remap = true })
@ -97,49 +96,17 @@ function M.create()
name = plugin.name, name = plugin.name,
kind = plugin._.kind, kind = plugin._.kind,
} }
self.state.plugin = not vim.deep_equal(self.state.plugin, selected) and selected or nil
local open = not vim.deep_equal(self.state.plugin, selected)
if not open then
local row = self.render:get_row(selected)
if row then
vim.api.nvim_win_set_cursor(self.view.win, { row, 8 })
end
end
self.state.plugin = open and selected or nil
self:update() self:update()
end end
end, "Details") end)
self:on_key(ViewConfig.keys.next, function()
local cursor = vim.api.nvim_win_get_cursor(self.view.win)
for l = 1, #self.render.locations, 1 do
local loc = self.render.locations[l]
if loc.from > cursor[1] then
vim.api.nvim_win_set_cursor(self.view.win, { loc.from, 8 })
return
end
end
end, "Next Plugin")
self:on_key(ViewConfig.keys.prev, function()
local cursor = vim.api.nvim_win_get_cursor(self.view.win)
for l = #self.render.locations, 1, -1 do
local loc = self.render.locations[l]
if loc.from < cursor[1] then
vim.api.nvim_win_set_cursor(self.view.win, { loc.from, 8 })
return
end
end
end, "Prev Plugin")
self:on_key(ViewConfig.keys.profile_sort, function() self:on_key(ViewConfig.keys.profile_sort, function()
if self.state.mode == "profile" then if self.state.mode == "profile" then
self.state.profile.sort_time_taken = not self.state.profile.sort_time_taken self.state.profile.sort_time_taken = not self.state.profile.sort_time_taken
self:update() self:update()
end end
end, "Sort Profile") end)
self:on_key(ViewConfig.keys.profile_filter, function() self:on_key(ViewConfig.keys.profile_filter, function()
if self.state.mode == "profile" then if self.state.mode == "profile" then
@ -159,18 +126,17 @@ function M.create()
end end
end) end)
end end
end, "Filter Profile") end)
for lhs, rhs in pairs(Config.options.ui.custom_keys) do for lhs, rhs in pairs(Config.options.ui.custom_keys) do
if rhs then if rhs then
local handler = type(rhs) == "table" and rhs[1] or rhs local handler = type(rhs) == "table" and rhs[1] or rhs
local desc = type(rhs) == "table" and rhs.desc or nil
self:on_key(lhs, function() self:on_key(lhs, function()
local plugin = self.render:get_plugin() local plugin = self.render:get_plugin()
if plugin then if plugin then
handler(plugin) handler(plugin)
end end
end, desc) end)
end end
end end
@ -181,7 +147,13 @@ end
function M:update() function M:update()
if self.buf and vim.api.nvim_buf_is_valid(self.buf) then if self.buf and vim.api.nvim_buf_is_valid(self.buf) then
vim.bo[self.buf].modifiable = true
local view = vim.api.nvim_win_call(self.view.win, vim.fn.winsaveview)
self.render:update() self.render:update()
vim.api.nvim_win_call(self.view.win, function()
vim.fn.winrestview(view)
end)
vim.bo[self.buf].modifiable = false
vim.cmd.redraw() vim.cmd.redraw()
end end
end end
@ -220,17 +192,17 @@ function M:setup_patterns()
["(https?://%S+)"] = function(url) ["(https?://%S+)"] = function(url)
Util.open(url) Util.open(url)
end, end,
}, self.hover, "Hover") }, self.hover)
self:on_pattern(ViewConfig.keys.diff, { self:on_pattern(ViewConfig.keys.diff, {
[commit_pattern] = function(hash) [commit_pattern] = function(hash)
self:diff({ commit = hash }) self:diff({ commit = hash })
end, end,
}, self.diff, "Diff") }, self.diff)
self:on_pattern(ViewConfig.commands.restore.key_plugin, { self:on_pattern(ViewConfig.commands.restore.key_plugin, {
[commit_pattern] = function(hash) [commit_pattern] = function(hash)
self:restore({ commit = hash }) self:restore({ commit = hash })
end, end,
}, self.restore, "Restore") }, self.restore)
end end
---@param opts? {commit:string} ---@param opts? {commit:string}
@ -295,8 +267,7 @@ end
---@param key string ---@param key string
---@param patterns table<string, fun(str:string)> ---@param patterns table<string, fun(str:string)>
---@param fallback? fun(self) ---@param fallback? fun(self)
---@param desc? string function M:on_pattern(key, patterns, fallback)
function M:on_pattern(key, patterns, fallback, desc)
self:on_key(key, function() self:on_key(key, function()
local line = vim.api.nvim_get_current_line() local line = vim.api.nvim_get_current_line()
local pos = vim.api.nvim_win_get_cursor(0) local pos = vim.api.nvim_win_get_cursor(0)
@ -318,7 +289,7 @@ function M:on_pattern(key, patterns, fallback, desc)
if fallback then if fallback then
fallback(self) fallback(self)
end end
end, desc) end)
end end
function M:setup_modes() function M:setup_modes()

View File

@ -74,17 +74,7 @@ function M:update()
end end
self:trim() self:trim()
vim.bo[self.view.buf].modifiable = true
local view = vim.api.nvim_win_call(self.view.win, vim.fn.winsaveview)
self:render(self.view.buf) self:render(self.view.buf)
vim.api.nvim_win_call(self.view.win, function()
vim.fn.winrestview(view)
end)
vim.bo[self.view.buf].modifiable = false
vim.diagnostic.set( vim.diagnostic.set(
Config.ns, Config.ns,
self.view.buf, self.view.buf,
@ -94,7 +84,7 @@ function M:update()
diag.lnum = diag.row - 1 diag.lnum = diag.row - 1
return diag return diag
end, self._diagnostics), end, self._diagnostics),
{ signs = false, virtual_text = true, underline = false, virtual_lines = false } { signs = false, virtual_text = true, underline = false }
) )
end end
@ -122,15 +112,6 @@ function M:get_plugin(row)
end end
end end
---@param selected {name:string, kind?: LazyPluginKind}
function M:get_row(selected)
for _, loc in ipairs(self.locations) do
if loc.kind == selected.kind and loc.name == selected.name then
return loc.from
end
end
end
function M:title() function M:title()
self:nl() self:nl()
local modes = vim.tbl_filter(function(c) local modes = vim.tbl_filter(function(c)
@ -144,6 +125,8 @@ function M:title()
if mode.name == "home" then if mode.name == "home" then
if self.view.state.mode == "home" then if self.view.state.mode == "home" then
title = " lazy.nvim " .. Config.options.ui.icons.lazy title = " lazy.nvim " .. Config.options.ui.icons.lazy
else
title = " lazy.nvim (H) "
end end
end end
@ -199,15 +182,7 @@ function M:help()
:nl() :nl()
self:append("or the plugin was just updated. Otherwise the plugin webpage will open."):nl():nl() self:append("or the plugin was just updated. Otherwise the plugin webpage will open."):nl():nl()
self:append("Use "):append("<d>", "LazySpecial"):append(" on a commit or plugin to open the diff view"):nl():nl() self:append("Use "):append("<d>", "LazySpecial"):append(" on a commit or plugin to open the diff view"):nl()
self
:append("Use ")
:append("<]]>", "LazySpecial")
:append(" and ")
:append("<[[>", "LazySpecial")
:append(" to navigate between plugins")
:nl()
:nl()
self:nl() self:nl()
self:append("Keyboard Shortcuts", "LazyH2"):nl() self:append("Keyboard Shortcuts", "LazyH2"):nl()
@ -759,7 +734,7 @@ function M:debug()
---@type string[] ---@type string[]
plugins = vim.tbl_values(plugins) plugins = vim.tbl_values(plugins)
table.sort(plugins) table.sort(plugins)
self:append(Config.options.ui.icons.debug, "LazySpecial", { indent = 2 }) self:append("", "LazySpecial", { indent = 2 })
if handler_type == "keys" then if handler_type == "keys" then
for k, v in pairs(Config.plugins[plugins[1]]._.handlers.keys) do for k, v in pairs(Config.plugins[plugins[1]]._.handlers.keys) do
if k == value then if k == value then

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
nvim -l tests/minit.lua --minitest "$@"

View File

@ -5,8 +5,7 @@ vim.env.LAZY_STDPATH = ".tests"
vim.opt.rtp:prepend(".") vim.opt.rtp:prepend(".")
-- Setup lazy.nvim -- Setup lazy.nvim
require("lazy.minit").setup({ require("lazy.minit").busted({
spec = { spec = {},
{ dir = vim.uv.cwd() }, stdpath = ".tests",
},
}) })

View File

@ -1,3 +1,4 @@
---@module 'luassert'
local Util = require("lazy.core.util") local Util = require("lazy.core.util")
describe("init", function() describe("init", function()

View File

@ -1,3 +1,5 @@
---@module 'luassert'
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Handler = require("lazy.core.handler") local Handler = require("lazy.core.handler")
local Plugin = require("lazy.core.plugin") local Plugin = require("lazy.core.plugin")
@ -25,7 +27,6 @@ local function clean(plugins)
if plugin._.dep == false then if plugin._.dep == false then
plugin._.dep = nil plugin._.dep = nil
end end
plugin._.top = nil
return plugin return plugin
end, plugins) end, plugins)
end end

View File

@ -1,3 +1,4 @@
---@module 'luassert'
local Keys = require("lazy.core.handler.keys") local Keys = require("lazy.core.handler.keys")
describe("keys", function() describe("keys", function()

View File

@ -1,3 +1,4 @@
---@module 'luassert'
local Async = require("lazy.async") local Async = require("lazy.async")
local Process = require("lazy.manage.process") local Process = require("lazy.manage.process")

View File

@ -1,4 +1,3 @@
local Async = require("lazy.async")
local Runner = require("lazy.manage.runner") local Runner = require("lazy.manage.runner")
describe("runner", function() describe("runner", function()
@ -34,7 +33,7 @@ describe("runner", function()
---@async ---@async
---@param task LazyTask ---@param task LazyTask
run = function(task) run = function(task)
Async.yield() coroutine.yield()
table.insert(runs, { plugin = task.plugin.name, task = task.name }) table.insert(runs, { plugin = task.plugin.name, task = task.name })
end, end,
} }

View File

@ -1,5 +1,5 @@
---@module 'luassert'
--# selene:allow(incorrect_standard_library_use) --# selene:allow(incorrect_standard_library_use)
local Async = require("lazy.async")
local Task = require("lazy.manage.task") local Task = require("lazy.manage.task")
describe("task", function() describe("task", function()
@ -43,7 +43,7 @@ describe("task", function()
local running = true local running = true
---@async ---@async
local task = Task.new(plugin, "test", function() local task = Task.new(plugin, "test", function()
Async.yield() coroutine.yield()
running = false running = false
end, opts) end, opts)
assert(task:running()) assert(task:running())

3
tests/run Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
nvim -l tests/busted.lua tests -o utfTerminal "$@"

21
vim.toml Normal file
View File

@ -0,0 +1,21 @@
[selene]
base = "lua51"
name = "vim"
[vim]
any = true
[jit]
any = true
[assert]
any = true
[describe]
any = true
[it]
any = true
[before_each.args]
any = true

19
vim.yml
View File

@ -1,19 +0,0 @@
base: lua51
lua_versions:
- luajit
globals:
Snacks:
any: true
vim:
any: true
jit:
any: true
assert:
any: true
describe:
any: true
it:
any: true
before_each:
any: true