Merge remote-tracking branch 'upstream/main'

This commit is contained in:
PartyWumpus 2025-09-17 18:51:17 +01:00
commit 31eb99a846
360 changed files with 11321 additions and 6338 deletions

View file

@ -14,15 +14,17 @@ indent_style = space
indent_size = 2
trim_trailing_whitespace = false
[*.{js,nix,yml,yaml}]
[*.{js,json,nix,yml,yaml,toml}]
indent_style = space
indent_size = 2
tab_width = 2
[*.{diff,patch}]
[*.{diff,patch,lock}]
end_of_line = unset
insert_final_newline = unset
trim_trailing_whitespace = unset
[*.lock]
[npins/sources.json]
indent_style = unset
indent_size = unset
trim_trailing_whitespace = unset

6
.github/CODEOWNERS vendored
View file

@ -1 +1,5 @@
* @NotAShelf
# Codeowners should be used to distinguish the maintainers of the project
# and not contributors of specific modules to nvf. While adding a new module
# please consider adding yourself to 'meta.maintainers' in the module instead
# of CODEOWNERS here.
* @NotAShelf @horriblename @Soliprem

View file

@ -2,48 +2,72 @@
## Table of Contents
- [Welcome](#welcome)
- [Contributing](#contributing)
- [Preface](#preface)
- [Contributing Process](#contributing-process)
- [Code of Conduct](#code-of-conduct)
## Welcome
## Preface
I'm glad you are thinking about contributing to nvf! If you're unsure about
anything, just ask - or submit the issue or pull request anyway. The worst that
can happen is you'll be politely asked to change something. Friendly
contributions are always welcome.
[LICENSE]: ../LICENSE
Before you contribute, I encourage you to read this project's CONTRIBUTING
policy (you are here) and its [LICENSE](../LICENSE) to understand how your
contributions are licensed.
I am glad you are thinking about contributing to nvf! The project is shaped by
contributors and user feedback, and all contributions are appreciated.
If you have any questions regarding those files, feel free to open an issue or
[shoot me an email](mailto:me@notashelf.dev). Discussions tab is also available
for more informal discussions.
If you are unsure about anything, whether a change is necessary or if it would
be accepted _had_ you created a PR, please just ask! Or submit the issue or pull
request anyway, the worst that can happen is that you will be politely asked to
change something. Friendly contributions are _always_ welcome.
## Contributing
Before you contribute, I encourage you to read the rest of this document for our
contributing policy and guidelines, followed by the [LICENSE] to understand how
your contributions are licensed.
The contribution process is mostly documented in the
[pull request template](PULL_REQUEST_TEMPLATE/pull_request_template.md). You
will find a checklist of items to complete before submitting a pull request.
Please make sure you complete it before submitting a pull request. If you are
If you have any questions regarding those files, or would like to ask a question
that is not covered by any of them, please feel free to open an issue!
Discussions tab is also available for less formal discussions. You may also
choose to contact me on Discord or Matrix if you would like to talk to me
personally.
## Contributing Process
[pull request template]: ./PULL_REQUEST_TEMPLATE.md
The contribution process is mostly documented in the [pull request template].
When you create a pull request, you will find a checklist of items to complete
before it can be submitted. We ask that you please complete it before submitting
a pull request to help maintainers provide more specific feedback. If you are
unsure about any of the items, please ask.
### Guidelines
We provide instructions on a healthy contribution to neovim-flake - including
styling, commit formats, how-to guides for adding new modules and options. You
are very well recommended to read the contributing guidelines over at
[the documentation](https://notashelf.github.io/nvf#hacking)
We provide instructions for a healthy contribution to nvf. This includes
**styling**, **commit formats**, **how-to guides for common contributions**. You
are strongly encouraged to read the contributing guidelines in full over at
[the documentation](https://notashelf.github.io/nvf#hacking).
A general gist of our requirements is that you must
1. Write clean Nix code
2. Self-test your changes
3. Document your changes
Though, please take a look at the manual for the complete contributing guide.
Please also feel free to let us know if you feel that something is missing. We
hope to provide clear, comprehensive instructions that make the contribution
process a breeze.
### Code of Conduct
This project does not quite have a code of conduct yet. And to be perfectly
honest, I'm not sure if I want one or if it will ever have one. I'm not
expecting this project to be a hotbed of activity, but I do want to make sure
that everyone who does contribute feels welcome and safe. As such, I will do my
best to make sure that those who distrupt the project are dealt with swiftly and
appropriately.
This project does not have a formal code of conduct yet, and to be perfectly
honest I am not entirely positive if I want one or if it will _ever_ have one.
This project is not expected to be a hotbed of activity, and I trust my
contributors to keep it civil and respectful.
I do, however, want to make sure that everyone who does contribute feels welcome
and safe around project spaces. As such, I will do my best to make sure anyone
who disrupts the project or engages in negative behaviour will are dealt with
appropriately, and swiftly. You are invited to share any concerns that you have
with the projects moderation, be it over public or private spaces.
If you feel that you are not being treated with respect, please contact me
directly.

View file

@ -1,60 +1,120 @@
name: "🐛 Bug Report"
description: "Submit a bug report to help us improve"
#title: "[Bug] "
description: "Submit a bug report to help us improve nvf"
title: "<short description of the bug>"
labels: [bug]
body:
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this bug has NOT been reported before."
description: "Search in the issues sections by clicking [HERE](https://github.com/notashelf/neovim-flake/issues?q=)"
label: I have confirmed that this is a bug related to nvf
description: >-
If you are unsure whether this is a bug, a packaging issue, or user error that is *not*
stemming from nvf, please consider creating a [discussion](https://github.com/notashelf/nvf/discussions)
post instead. Invalid bug reports will be closed without an explanation.
options:
- label: "I checked all existing issues and didn't find a similar issue"
required: true
- required: true
label: >-
This is a bug, and not an user error or a support request. I understand that my issue
will be closed if it is not a bug in nvf.
- required: true
label: >-
I have checked the [issues tab](https://github.com/notashelf/nvf/issues?q=is%3Aissue)
and confirmed that my issue has not yet been reported. I understand that my issue will
be closed if it is a duplicate.
- type: textarea
id: description
validations:
required: false
attributes:
label: "Description"
description: "You could also upload screenshots, if necessary"
label: Description
placeholder: "Describe the issue here..."
description: >-
Describe the issue in detail, with steps you have taken included. If applicable, please include
a minimal reproducible example, relevant Nix logs, comparisons with alternative commands and
screenshots. Do note that **logs** are preferred over screenshots.
validations:
required: true
- type: dropdown
attributes:
label: Installation Method
description: "How was nvf installed?"
options:
- NixOS Module (`nixosModules.default`)
- Home Manager Module (`homeManagerModules.default`)
- Standalone (flake outputs, `nix profile install`, etc.)
- Other
validations:
required: true
- type: textarea
attributes:
label: Installation Method (Other)
description: "If you have selected 'Other' in the previous section, please describe your installation method"
placeholder: >-
I installed nvf from...
- type: textarea
attributes:
label: nvf Version
description: "Which version of nvf are you using? If added as a flake input, write 'master'"
placeholder: >-
For example, v0.8 if consuming nvf from a tagged release.
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Reproduction steps
description: "How do you trigger this bug? Please walk us through the problem, step by step"
placeholder: >-
1. Do this
2. Do that
3. Observe
validations:
required: true
attributes:
label: "👟 Reproduction steps"
description: "How do you trigger this bug? Please walk us through the problem, step by step"
placeholder: "..."
- type: textarea
id: expected-behavior
validations:
required: true
attributes:
label: "👀 Expected behavior"
label: Expected behavior
description: "What did you think would or should happen?"
placeholder: "..."
validations:
required: true
- type: textarea
id: actual-behavior
validations:
required: true
attributes:
label: "😓 Actual Behavior"
label: Actual Behavior
description: "What actually happen?"
placeholder: "..."
- type: input
id: nix-metadata
attributes:
label: "💻 Metadata"
description: 'Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.'
placeholder: '[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"'
validations:
required: true
- type: textarea
attributes:
label: System Information
description: "Output of `nix-info --markdown`"
render: bash
placeholder: |-
'[user@system:~]$ nix-shell -p nix-info --run "nix-info --markdown"
- system:
- host os:
- multi-user?:
- sandbox:
- version:
- nixpkgs:
validations:
required: true
- type: textarea
id: logs
attributes:
label: "📝 Relevant log output"
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: bash
label: "Relevant log output"
description: >-
Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
> [!TIP]
> You can get your nvf configuration with `nvf-print-config` and attach it by using a service like termbin.com
validations:
required: true

View file

@ -1,58 +1,72 @@
name: 🚀 Feature Request
description: "Propose a new feature"
#title: "[Feature] "
title: "<short description of the desired addition>"
labels: [feature-request]
body:
- type: checkboxes
id: no-duplicate-issues
attributes:
label: "⚠️ Please verify that this feature request has NOT been suggested before."
description: "Search in the issues sections by clicking [HERE](https://github.com/notashelf/neovim-flake/issues?q=)"
label: I have verified that this feature request has not been made before
description: >-
Before opening a new issue for feature requests, please consider searching through currently
open issues [here](https://github.com/notashelf/nvf/issues). If you would like to discuss a
new addition beforehand, you may first want to create a new discussion threat and discuss it
with the maintainers [on the discussions tab](https://github.com/notashelf/nvf/discussions)
options:
- label: "I checked and didn't find a similar feature request"
required: true
- required: true
label: >-
I have checked the [issues tab](https://github.com/notashelf/nvf/issues?q=is%3Aissue),
and did not find a similar feature request. I understand that my issue will be closed
if it is a duplicate.
- type: dropdown
id: feature-area
attributes:
label: "🏷️ Feature Type"
description: "What kind of a feature request is this?"
label: Feature Type
description: Please describe the kind of addition this is
multiple: true
options:
- New Command
- New Addon
- API Additions
- New Plugin
- Update Request (Plugin/Nixpkgs)
- Documentation Updates
- Other
validations:
required: true
- type: textarea
id: feature-description
attributes:
label: Feature description
description: >-
Please provide a clear and concise description of the desired addition. If this is a plugin
addition, please also include a link to the desired plugin and the reason why you think this
is a good addition. Keep in mind that we may refuse plugin requests as nvf already provides
appropriate methods of installing plugins in user configurations.
placeholder: >-
"nvf currently does [...], which really frustrates me" or "You should add [...] because I think
[...]"
validations:
required: true
attributes:
label: "🔖 Feature description"
description: "A clear and concise description of what your feature request is."
placeholder: "'You should add [...]' or '[...] has always frustrated me' "
- type: textarea
id: solution
validations:
required: true
attributes:
label: "✔️ Solution"
description: "A clear and concise description of what you want to happen."
placeholder: "In my use-case, I would like [...]"
- type: textarea
id: alternatives
attributes:
label: Alternatives
description: >-
If you have tried anything before creating this issue, please give us a clear and concise
description of any alternative solutions or methods you have considered.
placeholder: "I have considered [...]"
validations:
required: false
attributes:
label: "❓ Alternatives"
description: "A clear and concise description of any alternative solutions or features you've considered."
placeholder: "I have considered [...]"
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: >-
If there is anything else you would like to mention, such as additional context or screenshots
demonstrating the requested feature, please add them here. This field is optional, but you may
be requested to provide further context. Please ensure that your feature request clearly describes
the requested feature in good detail.
validations:
required: false
attributes:
label: "📝 Additional Context"
description: "Add any other context or screenshots about the feature request here."
placeholder: "..."

View file

@ -7,14 +7,17 @@ or dependency in this section.
If your pull request aims to fix an open issue or a please bug, please also link the relevant issue
below this line. You may attach an issue to your pull request with `Fixes #<issue number>` outside
this comment, and it will be closed when your pull request is merged.
A developer package template is provided in flake/develop.nix. If working on a module, you may use
it to test your changes with minimal dependency changes.
-->
## Sanity Checking
<!--
Please check all that apply. As before, this section is not a hard requirement but checklists with more checked
items are likely to be merged faster. You may save some time in maintainer review by performing self-reviews here
before submitting your pull request.
items are likely to be merged faster. You may save some time in maintainer reviews by performing self-reviews
here before submitting your pull request.
If your pull request includes any change or unexpected behaviour not covered below, please do make sure to include
it above in your description.
@ -22,9 +25,11 @@ it above in your description.
[editorconfig]: https://editorconfig.org
[changelog]: https://github.com/NotAShelf/nvf/tree/main/docs/release-notes
[hacking nvf]: https://notashelf.github.io/nvf/index.xhtml#sec-guidelines
- [ ] I have updated the [changelog] as per my changes
- [ ] I have tested, and self-reviewed my code
- [ ] My changes fit guidelines found in [hacking nvf]
- Style and consistency
- [ ] I ran **Alejandra** to format my code (`nix fmt`)
- [ ] My code conforms to the [editorconfig] configuration of the project
@ -34,9 +39,10 @@ it above in your description.
- [ ] I have added a section in the manual
- [ ] _(For breaking changes)_ I have included a migration guide
- Package(s) built:
- [ ] `.#nix` (default package)
- [ ] `.#nix` _(default package)_
- [ ] `.#maximal`
- [ ] `.#docs-html` (manual, must build)
- [ ] `.#docs-html` _(manual, must build)_
- [ ] `.#docs-linkcheck` _(optional, please build if adding links)_
- Tested on platform(s)
- [ ] `x86_64-linux`
- [ ] `aarch64-linux`
@ -46,7 +52,8 @@ it above in your description.
<!--
If your changes touch upon a portion of the codebase that you do not understand well, please make sure to consult
the maintainers on your changes. In most cases, making an issue before creating your PR will help you avoid duplicate
efforts in the long run.
efforts in the long run. `git blame` might help you find out who is the "author" or the "maintainer" of a current
module by showing who worked on it the most.
-->
---

55
.github/labels.yml vendored Normal file
View file

@ -0,0 +1,55 @@
# This file is used by .github/workflows/labels.yml
"topic: plugins":
- any:
- changed-files:
- any-glob-to-any-file:
- modules/plugins/**/*
"topic: modules":
- any:
- changed-files:
- any-glob-to-any-file:
- modules/**/*
"topic: dependencies":
- any:
- changed-files:
- any-glob-to-any-file:
- npins
- flake.lock
"topic: CI":
- any:
- changed-files:
- any-glob-to-any-file:
- .github/workflows/*.yml
- .github/typos.toml
- .github/dependabot.yml
"topic: meta":
- any:
- changed-files:
- any-glob-to-any-file:
- .github/CODEOWNERS
- LICENSE
- .github/README.md
- .github/funding.yml
- .github/assets
- .github/*_TEMPLATE
- .gitignore
- .editorconfig
- release.json
"topic: documentation":
- any:
- changed-files:
- any-glob-to-any-file:
- docs/**/*
- .github/CONTRIBUTING.md
- .github/README.md
"topic: packaging":
- any:
- changed-files:
- any-glob-to-any-file:
- flake.nix
- flake/packages.nix

10
.github/typos.toml vendored
View file

@ -1,2 +1,10 @@
default.extend-ignore-words-re = ["(?i)(noice)", "befores", "annote", "viw"]
files.extend-exclude = ["npins/sources.json"]
default.extend-ignore-words-re = [
"(?i)(noice)",
"befores",
"annote",
"viw",
"BA", # somehow "BANanaD3V" is valid, but BA is not...
]

33
.github/workflows/backport.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: Backport PR on Label
on:
pull_request_target:
types:
- labeled
# Permissions needed for the korthout/backport-action to create branches and PRs
permissions:
contents: write
pull-requests: write
jobs:
backport:
name: Create Backport PR
runs-on: ubuntu-latest
if: |
github.event.pull_request.merged == true && startsWith(github.event.label.name, 'backport-')
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
token: ${{ steps.app-token.outputs.token }}
- name: Backport Action
uses: korthout/backport-action@v3
with:
# Regex pattern for labels that should trigger a backport AND extracts the target branch
# from the name (e.g. v0.x or v0.x.y; we use zerover). This action will ONLY proceed if
# the label that triggered the workflow fully matches this pattern.
# Example matching labels: "backport-v0.1", "backport-v0.10.1"
# Example non-matching labels: "backport-foo", "backport-v1.0"
label_pattern: '^backport-(v0\.\d+(\.\d+)?)$'

View file

@ -21,23 +21,13 @@ jobs:
- nix
- maximal
steps:
- uses: easimon/maximize-build-space@v10
name: Maximize build space
with:
overprovision-lvm: true
remove-android: true
remove-dotnet: true
remove-haskell: true
remove-codeql: true
- uses: actions/checkout@v4
- uses: actions/checkout@v5
name: Checkout
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@v16
with:
authToken: ${{ secrets.CACHIX_TOKEN }}
extraPullNames: nix-community

View file

@ -1,57 +0,0 @@
name: "Validate flake & check documentation"
on:
pull_request:
workflow_dispatch:
push:
branches:
- main
paths:
- docs/**
jobs:
flake-docs-check:
name: Validate Flake Documentation
runs-on: ubuntu-latest
strategy:
matrix:
package:
- docs
- docs-html
- docs-manpages
- docs-json
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Checkout
uses: actions/checkout@v4
- name: Set default git branch (to reduce log spam)
run: git config --global init.defaultBranch main
- name: Build documentation packages
run: nix build .#${{ matrix.package }} --print-build-logs
- name: Get current date
id: get-date
# output format: 2023-12-22-120000
run: echo "date=$(date +'%Y-%m-%d-%H%M%S')" >> ${GITHUB_OUTPUT}
- name: Upload doc artifacts
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.package }}"
path: result/share/doc/nvf
flake-docs-linkcheck:
name: Validate hyperlinks in documentation sources
runs-on: ubuntu-latest
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Checkout
uses: actions/checkout@v4
- name: Build documentation packages
run: nix build .#docs-linkcheck -Lv

View file

@ -1,4 +1,6 @@
name: "Validate flake & check formatting"
name: "Treewide Checks"
permissions: read-all
on:
pull_request:
workflow_dispatch:
@ -6,33 +8,158 @@ on:
branches:
- main
paths-ignore:
- .github/**
- assets/**
- .gitignore
jobs:
nix-flake-check:
name: Validate Flake
name: "Validate flake"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Check Flake
run: nix flake check
format-with-alejandra:
name: Formatting via Alejandra
name: "Check formatting"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- run: nix run nixpkgs#alejandra -- -c .
- name: Check formatting via Alejandra
run: nix run nixpkgs#alejandra -- --check . --exclude npins
- name: Check formatting via Deno
run: nix run nixpkgs#deno -- fmt --check --ext md **/*.md
- if: ${{ failure() }}
shell: bash
run: |
echo "::error:: Current codebase contains formatting errors that were caught by the CI!"
echo "Please ensure that all Nix code is formatted with Alejandra, and Markdown with `deno fmt"
echo "[skip ci] label may be added to the PR title if this is a one-time issue and is safe to ignore"
exit 1
check-typos:
name: "Check source tree for typos"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Check for typos
uses: crate-ci/typos@master
with:
config: .github/typos.toml
- if: ${{ failure() }}
shell: bash
run: |
echo "::error:: Current codebase contains typos that were caught by the CI!"
echo "If those typos were intentional, please add them to the ignored regexes in .github/typos.toml"
echo "[skip ci] label may be added to the PR title if this is a one-time issue and is safe to ignore"
exit 1
flake-docs-check:
name: "Validate documentation builds"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
strategy:
matrix:
package:
- docs
- docs-html
- docs-manpages
- docs-json
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Checkout
uses: actions/checkout@v5
- name: Set default git branch (to reduce log spam)
run: git config --global init.defaultBranch main
- name: Build documentation packages
run: nix build .#${{ matrix.package }} --print-build-logs
- name: Get current date
id: get-date
# output format: 2023-12-22-120000
run: echo "date=$(date +'%Y-%m-%d-%H%M%S')" >> ${GITHUB_OUTPUT}
- name: Upload doc artifacts
uses: actions/upload-artifact@v4
with:
name: "${{ matrix.package }}"
path: result/share/doc/nvf
flake-docs-linkcheck:
name: "Validate hyperlinks in documentation sources"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Checkout
uses: actions/checkout@v5
- name: Build linkcheck package
run: nix build .#docs-linkcheck -Lv
check-editorconfig:
name: "Validate Editorconfig conformance"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 2 # slows down checkout, but we need to compare against the previous commit on push events
- name: Get list of changed files from PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
gh api repos/${{ github.repository }}/pulls/${{ github.event.number }}/files --paginate \
| jq -r '.[] | select(.status != "removed") | .filename' \
> "$HOME/changed_files"
else
git diff --name-only HEAD^ > "$HOME/changed_files"
fi
- name: Print list of changed files
run: |
cat "$HOME/changed_files"
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- name: Checking Editorconfig conformance
shell: bash
run: |
< "$HOME/changed_files" nix-shell -p editorconfig-checker \
--run 'xargs -r editorconfig-checker -disable-indent-size --exclude flake.lock'
- if: ${{ failure() }}
shell: bash
run: |
echo "::error:: Current formatting does not fit convention provided by .editorconfig located in the project root."
echo "Please make sure your editor properly integrates editorconfig, Neovim does so by default."
echo "See https://editorconfig.org/#download on how to integrate Editorconfig to your editor."
exit 1

View file

@ -1,19 +1,23 @@
name: Cleanup
name: Delete Stale Branches
permissions:
contents: write
on:
workflow_dispatch:
schedule:
- cron: "0 4 1 * *" # 4AM on 1st of every month
- cron: "0 4 15 * *" # 4AM on the 15th of every month
jobs:
branches:
name: Cleanup old branches
runs-on: ubuntu-latest
steps:
- name: "Checkout"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Delete old branches"
uses: beatlabs/delete-old-branches-action@v0.0.10
uses: beatlabs/delete-old-branches-action@v0.0.11
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
date: "1 months ago"

View file

@ -9,7 +9,7 @@ on:
- "modules/**"
- "docs/**"
# Defining permissions here passes it to all workflows.
# Defining permissions here passes it to all jobs.
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token
permissions:
contents: write
@ -26,16 +26,15 @@ jobs:
steps:
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set default git branch (to reduce log spam)
run: git config --global init.defaultBranch main
- name: Build documentation packages
run: nix build .#docs-html --print-build-logs
run: nix build .#docs-html --print-build-logs || exit 1
- name: Deploy to GitHub Pages preview
run: |
@ -128,7 +127,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Delete preview for closed/merged PR
run: |
@ -165,7 +164,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Double check preview directory deletion
run: |

View file

@ -1,47 +0,0 @@
name: "Check validity of .editorconfig"
permissions: read-all
on:
pull_request:
jobs:
check-editorconfig:
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Get list of changed files from PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api \
repos/notashelf/nvf/pulls/${{github.event.number}}/files --paginate \
| jq '.[] | select(.status != "removed") | .filename' \
> "$HOME/changed_files"
- name: Print list of changed files
run: |
cat "$HOME/changed_files"
- name: Checkout
uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Install Nix
uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- name: Checking EditorConfig
shell: bash
run: |
cat "$HOME/changed_files" | nix-shell -p editorconfig-checker.out --run 'xargs -r editorconfig-checker -disable-indentation -exclude flake.lock --verbose'
echo -n "Check status: $?"
- name: Fail Gracefully
if: ${{ failure() }}
shell: bash
run: |
echo "::error:: Current formatting does not fit convention provided by .editorconfig located in the project root."
echo "Please make sure your editor properly integrates editorconfig. See https://editorconfig.org/#download for more."
exit 1

21
.github/workflows/labeler.yml vendored Normal file
View file

@ -0,0 +1,21 @@
name: "Label PR"
on:
pull_request_target:
types: [edited, opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
labels:
name: "Label PR"
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- uses: actions/labeler@v6
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/labels.yml
sync-labels: true

View file

@ -28,7 +28,7 @@ jobs:
outputs:
should_run: ${{ steps.should_run.outputs.should_run }}
steps:
- uses: actions/checkout@v4.1.7
- uses: actions/checkout@v5
- name: print latest_commit
run: echo ${{ github.sha }}
@ -43,9 +43,8 @@ jobs:
if: ${{ needs.check_date.outputs.should_run != 'false' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.7
- uses: actions/checkout@v5
- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main
- run: |
nix build .#docs -Lv
cp -r result/share/doc/nvf public

View file

@ -1,30 +0,0 @@
name: "Check for typos in the source tree"
permissions: read-all
on:
pull_request:
workflow_dispatch:
push:
jobs:
check-typos:
runs-on: ubuntu-latest
if: "!contains(github.event.pull_request.title, '[skip ci]')"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check for typos
uses: crate-ci/typos@master
with:
config: .github/typos.toml
- name: Fail Gracefully
if: ${{ failure() }}
shell: bash
run: |
echo "::error:: Current codebase contains typos that were caught by the CI!"
echo "If those typos were intentional, please add them to the ignored regexes in .github/typos.toml"
echo "[skip ci] label may be used if this is a one-time issue"
exit 1

View file

@ -1,5 +1,6 @@
<!-- markdownlint-disable MD013 MD033 MD041-->
<div align="center">
<img src="assets/nvf-logo-work.svg" alt="nvf Logo" width="200">
<img src=".github/assets/nvf-logo-work.svg" alt="nvf Logo" width="192">
<br/>
<h1>nvf</h1>
</div>
@ -46,7 +47,7 @@
[Features]: #features
[Get Started]: #get-started
[Documentation]: #documentation
[Help]: #help
[Help]: #getting-help
[Contribute]: #contributing
[FAQ]: #frequently-asked-questions
[Credits]: #credits
@ -67,6 +68,10 @@
[standalone]: https://notashelf.github.io/nvf/index.xhtml#ch-standalone-installation
[NixOS module]: https://notashelf.github.io/nvf/index.xhtml#ch-standalone-nixos
[Home-Manager module]: https://notashelf.github.io/nvf/index.xhtml#ch-standalone-hm
[release notes]: https://notashelf.github.io/nvf/release-notes.html
[discussions tab]: https://github.com/notashelf/nvf/discussions
[FAQ section]: #frequently-asked-questions
[DAG]: https://en.wikipedia.org/wiki/Directed_acyclic_graph
- **Simple**: One language to rule them all! Use Nix to configure everything,
with optional Lua support for robust configurability!
@ -79,11 +84,32 @@
customizable through the Nix module system.
- Not comfortable with a full-nix config or want to bring your Lua config? You
can do just that, no unnecessary restrictions.
- Lazyloading? We got it! Lazyload both internal and external plugins at will.
- Lazyloading? We got it! Lazyload both internal and external plugins at will
💤 .
- nvf allows _ordering configuration bits_ using [DAG] (_Directed acyclic
graph_)s. It has never been easier to construct an editor configuration
deterministically!
- nvf exposes everything you need to avoid a vendor lock-in. Which means you
can add new modules, plugins and so on without relying on us adding a module
for them! Though, of course, feel free to request them.
- Use plugins from anywhere: inputs, npins, nixpkgs... You name it.
- Add your own modules with ease. It's all built-in!
- **Well-documented**: Documentation is priority. You will _never_ face
undocumented, obscure behaviour.
- Any and all changes, breaking or otherwise, will be communicated in the
[release notes].
- Refer to the [FAQ section] for answers to common questions.
- Your question not there? Head to the [discussions tab]!
- **Idiomatic**: nvf does things ✨ _the right way_ ✨ - the codebase is, and
will, remain maintainable for myself and any contributors.
- **Community-Led**: we would like nvf to be fully capable of accomplishing what
you really want it to do. If you have a use case that is not made possible by
nvf, please open an issue (or a pull request!)
- Your feedback is more than welcome! Feedback is what _drives_ nvf forward.
If you have anything to say, or ask, please let us know.
- Pull requests are _always_ welcome. If you think the project can benefit
from something you did locally, but are not quite sure how to upstream,
please feel free to contact us! We'll help you get it done.
## Get Started
@ -96,7 +122,7 @@ the following in order to take **nvf** out for a spin.
```bash
# Run the default package
nix run github:notashelf/nvf
$ nix run github:notashelf/nvf
```
This will get you a feel for the base configuration and UI design. Though, none
@ -104,20 +130,25 @@ of the configuration options are final as **nvf** is designed to be modular and
configurable.
> [!TIP]
> The flake exposes `#nix` as the default package, providing minimal language
> support and various utilities. You may also use the `#nix` or `#maximal`
> packages provided by the this flake to get try out different configurations.
> The flake exposes `nix` as the default package, which will be evaluated when
> you run `nix build` or `nix run` on this repo. It is minimal, and providing
> limited language support and various utilities. We also expose the `maximal`
> package, which you may choose to build if you'd like to see more of nvf's
> built-in modules. Please keep in mind that those are demo packages, nvf does
> not ship a default configuration if installed as a NixOS/Home-Manager module
> or via standalone method.
It is as simple as changing the target output to get a different configuration.
For example, to get a configuration with large language coverage, run:
It is as simple as changing the target output in your `nix run` command to get a
different configuration. For example, to get a configuration with large language
coverage, run:
```bash
# Run the maximal package
nix run github:notashelf/nvf#maximal
$ nix run github:notashelf/nvf#maximal
```
Similar instructions will apply for `nix profile install`. However, you are
recommended to instead use the module system as described in the manual.
recommended to instead use the module system as described in the [nvf manual].
> [!NOTE]
> The `maximal` configuration is quite large, and might take a while to build.
@ -130,6 +161,10 @@ instructions.
## Documentation
**nvf** prides itself in its rich, intuitive documentation. The chapter below
covers several methods through which you can install **nvf**. If you believe
something is missing, or could be done better, please feel free to contact us!
### Installation
The _recommended_ way of installing nvf is using either the NixOS or the
@ -138,7 +173,7 @@ install **nvf** as a standalone package, or a flake output.
See the rendered [nvf manual] for detailed and up-to-date installation guides,
configurations, available options, release notes and more. Tips for installing
userspace plugins is also contained in the documentation.
userspace plugins are also contained in the documentation.
> [!TIP]
> While using NixOS or Home-Manager modules,
@ -155,16 +190,18 @@ requests are also welcome, and appreciated.
If you are confused, stuck or would like to ask a simple question; you may
create an issue on the [issue tracker] to ask questions or report bugs.
We are not not yet on spaces like matrix or IRC, so please use the issue tracker
for now.
We are not yet on spaces like matrix or IRC, so please use the issue tracker for
now. The [discussions tab] can also be a place to request help from community
members, or engage in productive discussion with the maintainers.
## Contributing
[contributing guide]: .github/CONTRIBUTING.md
I am always looking for new ways to help improve this flake. If you would like
to contribute, please read the [contributing guide](CONTRIBUTING.md) before
submitting a pull request. You can also create an issue on the [issue tracker]
before submitting a pull request if you would like to discuss a feature or bug
fix.
to contribute, please read the [contributing guide] before submitting a pull
request. You can also create an issue on the [issue tracker] before submitting a
pull request if you would like to discuss a feature or bug fix.
## Frequently Asked Questions
@ -173,49 +210,64 @@ fix.
[list of open pull requests]: https://github.com/NotAShelf/nvf/pulls
**Q**: What platforms are supported?
<br/> **A**: nvf actively supports **Linux and Darwin** platforms using
standalone Nix, NixOS or Home-Manager. Please take a look at the [nvf manual]
for available installation instructions.
**A**: nvf actively supports **Linux and Darwin** platforms using standalone
Nix, NixOS or Home-Manager. It has been reported that **Android** is also
supported through the Home-Manager module, or using standalone package. Please
take a look at the [nvf manual] for available installation instructions.
**Q**: Can you add _X_?
<br/> **A**: Maybe! It is not one of our goals to support each and every Neovim
**A**: Maybe! It is not one of our goals to support each and every Neovim
plugin, however, I am always open to new modules and plugin setup additions to
**nvf**. Use the appropriate [issue template] and I will consider a module
addition. As mentioned before, pull requests to add new features are also
welcome.
**Q**: A plugin I need is not available in **nvf**. What to do?
<br/> **A**: **nvf** exposes several APIs for you to be able to add your own
plugin configurations! Please see the documentation on how you may do this.
**A**: **nvf** exposes several APIs for you to be able to add your own plugin
configurations! Please see the documentation on how you may do this.
**Q**: Main branch is awfully silent, is the project dead?
<br/> **A**: No! Sometimes we branch out (e.g. `v0.6`) to avoid breaking
userspace and work in a separate branch until we make sure the new additions are
implemented in the most comfortable way possible for the end user. If you have
not noticed any activity on the main branch, consider taking a look at the
**A**: No! Sometimes we branch out (e.g. `v0.6`) to avoid breaking userspace and
work in a separate branch until we make sure the new additions are implemented
in the most comfortable way possible for the end user. If you have not noticed
any activity on the main branch, consider taking a look at the
[list of branches] or the [list of open pull requests]. You may also consider
_testing_ those release branches to get access to new features ahead of time and
better prepare to breaking changes.
better prepare for breaking changes.
**Q**: Will you support non-flake installations?
<br/> **A**: Quite possibly. **nvf** started as "neovim-flake", which does mean
it is and will remain flakes-first but we might consider non-flakes
compatibility. Though keep in mind that **nvf** under non-flake environments
would lose customizability of plugin inputs, which is one of our primary
features.
**A**: Quite possibly. **nvf** started as "neovim-flake", which does mean it is
and will remain flakes-first but we might consider non-flakes compatibility.
Though keep in mind that **nvf** under non-flake environments would lose
customizability of plugin inputs, which is one of our primary features.
**Q**: I prefer working with Lua, can I use nvf as a plugin manager while I use
an imperative path (e.g., `~/.config/nvim`) for my Neovim configuration instead
of a configuration generated from Nix?
**A**: Yes! Add `"~/.config/nvim"` to `vim.additionalRuntimePaths = [ ... ]` and
any plugins you want to load to `vim.startPlugins`. This will load your
configuration from `~/.config/nvim`. You may still use `vim.*` options in Nix to
further configure Neovim.
## Credits
### Co-Maintainers
Alongside myself, nvf is developed by those talented folk:
Alongside [myself](https://github.com/notashelf), nvf is developed by those
talented folk. **nvf** would not be what it is today without their invaluable
contributions.
- [**@horriblename**](https://github.com/horriblename)
([Liberapay](https://liberapay.com/horriblename/))- For actively implementing
([Liberapay](https://liberapay.com/horriblename/)) - For actively implementing
planned features and quality of life updates.
- [**@Diniamo**](https://github.com/Diniamo)
([Liberapay](https://en.liberapay.com/diniamo/)) - For actively submitting
pull requests, issues and assistance with maintenance of nvf.
- [**@Soliprem**](https://github.com/soliprem) - For rigorously implementing
missing features and excellent work on new language modules.
Please do remember to extend your thanks (financially or otherwise) if this
project has been helpful to you.
@ -232,20 +284,20 @@ heart-felt thanks to
- [**@FlafyDev**](https://github.com/FlafyDev) - For getting Home-Manager module
to work and Nix assistance.
- [**@n3oney**](https://github.com/n3oney) - For making custom keybinds finally
possible, and other module additions.
possible, great ideas and module additions.
- [**@Yavko**](https://github.com/Yavko) - For the amazing **nvf** logo
- [**@FrothyMarrow**](https://github.com/FrothyMarrow) - For seeing mistakes
that I could not.
that I could not and contributing good ideas & code.
- [**@Gerg-l**](https://github.com/gerg-l) 🐸 - For the modern Neovim wrapper,
[mnw], and occasional code improvements.
- [**@Soliprem**](https://github.com/soliprem) - Rigorously implementing missing
features and excellent work on new language modules.
[mnw], and occasional improvements to the codebase.
- [**@Diniamo**](https://github.com/Diniamo) - For actively submitting pull
requests, issues and assistance with co-maintenance of nvf.
and everyone who has submitted issues or pull requests!
### Inspiration
This configuration borrows from and is based on a few other configurations,
This configuration borrows from, and is based on a few other configurations,
including:
- [@jordanisaacs's](https://github.com/jordanisaacs)
@ -263,7 +315,6 @@ including:
I am grateful for their previous work and inspiration, and I wholeheartedly
recommend checking their work out.
<br/>
## License

View file

@ -1,6 +1,7 @@
# This is the sample configuration for nvf, aiming to give you a feel of the default options
# while certain plugins are enabled. While it may act as one, this is not an overview of nvf's
# module options. To find a complete overview of nvf's options and examples, visit the manual.
# while certain plugins are enabled. While it may partially act as one, this is *not* quite
# an overview of nvf's module options. To find a complete and curated list of nvf module
# options, examples, instruction tutorials and more; please visit the online manual.
# https://notashelf.github.io/nvf/options.html
isMaximal: {
config.vim = {
@ -14,17 +15,21 @@ isMaximal: {
spellcheck = {
enable = true;
programmingWordlist.enable = isMaximal;
};
lsp = {
# This must be enabled for the language modules to hook into
# the LSP API.
enable = true;
formatOnSave = true;
lspkind.enable = false;
lightbulb.enable = true;
lspsaga.enable = false;
trouble.enable = true;
lspSignature.enable = true;
lspSignature.enable = !isMaximal; # conflicts with blink in maximal
otter-nvim.enable = isMaximal;
lsplines.enable = isMaximal;
nvim-docs-view.enable = isMaximal;
};
@ -38,7 +43,6 @@ isMaximal: {
# This section does not include a comprehensive list of available language modules.
# To list all available language module options, please visit the nvf manual.
languages = {
enableLSP = true;
enableFormat = true;
enableTreesitter = true;
enableExtraDiagnostics = true;
@ -81,6 +85,7 @@ isMaximal: {
elixir.enable = false;
haskell.enable = false;
ruby.enable = false;
fsharp.enable = false;
tailwind.enable = false;
svelte.enable = false;
@ -123,7 +128,15 @@ isMaximal: {
autopairs.nvim-autopairs.enable = true;
autocomplete.nvim-cmp.enable = true;
# nvf provides various autocomplete options. The tried and tested nvim-cmp
# is enabled in default package, because it does not trigger a build. We
# enable blink-cmp in maximal because it needs to build its rust fuzzy
# matcher library.
autocomplete = {
nvim-cmp.enable = !isMaximal;
blink-cmp.enable = isMaximal;
};
snippets.luasnip.enable = true;
filetree = {
@ -149,6 +162,7 @@ isMaximal: {
enable = true;
gitsigns.enable = true;
gitsigns.codeActions.enable = false; # throws an annoying debug message
neogit.enable = isMaximal;
};
minimap = {
@ -172,17 +186,24 @@ isMaximal: {
utility = {
ccc.enable = false;
vim-wakatime.enable = false;
diffview-nvim.enable = true;
yanky-nvim.enable = false;
icon-picker.enable = isMaximal;
surround.enable = isMaximal;
diffview-nvim.enable = true;
leetcode-nvim.enable = isMaximal;
multicursors.enable = isMaximal;
smart-splits.enable = isMaximal;
undotree.enable = isMaximal;
nvim-biscuits.enable = isMaximal;
motion = {
hop.enable = true;
leap.enable = true;
precognition.enable = isMaximal;
};
images = {
image-nvim.enable = false;
img-clip.enable = isMaximal;
};
};
@ -230,6 +251,8 @@ isMaximal: {
enable = false;
cmp.enable = isMaximal;
};
codecompanion-nvim.enable = false;
avante-nvim.enable = isMaximal;
};
session = {

15
default.nix Normal file
View file

@ -0,0 +1,15 @@
(import (
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
inherit (lock.nodes.flake-compat.locked) url rev narHash;
in
builtins.fetchTarball {
url = "${url}/archive/${rev}.tar.gz";
sha256 = narHash;
}
) {
src = ./.;
copySourceTreeToStore = false;
useBuiltinsFetchTree = true;
})
.defaultNix

View file

@ -12,6 +12,7 @@
inherit
(
(lib.evalModules {
specialArgs = {inherit inputs;};
modules =
import ../modules/modules.nix {
inherit lib pkgs;
@ -95,8 +96,6 @@
inherit (nvimModuleDocs) optionsJSON;
};
in {
inherit (inputs) nmd;
# TODO: Use `hmOptionsDocs.optionsJSON` directly once upstream
# `nixosOptionsDoc` is more customizable.
options.json =

View file

@ -102,7 +102,7 @@ in
--script script/anchor-use.js \
--script script/anchor-min.js \
--script script/search.js \
--toc-depth 2 \
--toc-depth 1 \
--section-toc-depth 1 \
manual.md \
"$dest/index.xhtml"

View file

@ -1,10 +1,21 @@
# Configuring nvf {#ch-configuring}
[helpful tips section]: #ch-helpful-tips
nvf allows for _very_ extensive configuration in Neovim through the Nix module
interface. The below chapters describe several of the options exposed in nvf for
your convenience. You might also be interested in the [helpful tips section] for
more advanced or unusual configuration options supported by nvf.
Note that this section does not cover module _options_. For an overview of all
module options provided by nvf, please visit the [appendix](/nvf/options.html)
```{=include=} chapters
configuring/custom-package.md
configuring/custom-plugins.md
configuring/custom-inputs.md
configuring/overriding-plugins.md
configuring/languages.md
configuring/dags.md
configuring/dag-entries.md
configuring/autocmds.md
```

View file

@ -0,0 +1,119 @@
# Autocommands and Autogroups {#ch-autocmds-augroups}
This module allows you to declaratively configure Neovim autocommands and
autogroups within your Nix configuration.
## Autogroups (`vim.augroups`) {#sec-vim-augroups}
Autogroups (`augroup`) organize related autocommands. This allows them to be
managed collectively, such as clearing them all at once to prevent duplicates.
Each entry in the list is a submodule with the following options:
| Option | Type | Default | Description | Example |
| :------- | :----- | :------ | :--------------------------------------------------------------------------------------------------- | :---------------- |
| `enable` | `bool` | `true` | Enables or disables this autogroup definition. | `true` |
| `name` | `str` | _None_ | **Required.** The unique name for the autogroup. | `"MyFormatGroup"` |
| `clear` | `bool` | `true` | Clears any existing autocommands within this group before adding new ones defined in `vim.autocmds`. | `true` |
**Example:**
```nix
{
vim.augroups = [
{
name = "MyCustomAuGroup";
clear = true; # Clear previous autocommands in this group on reload
}
{
name = "Formatting";
# clear defaults to true
}
];
}
```
## Autocommands (`vim.autocmds`) {#sec-vim-autocmds}
Autocommands (`autocmd`) trigger actions based on events happening within Neovim
(e.g., saving a file, entering a buffer). Each entry in the list is a submodule
with the following options:
| Option | Type | Default | Description | Example |
| :--------- | :-------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------- |
| `enable` | `bool` | `true` | Enables or disables this autocommand definition. | `true` |
| `event` | `nullOr (listOf str)` | `null` | **Required.** List of Neovim events that trigger this autocommand (e.g., `BufWritePre`, `FileType`). | `[ "BufWritePre" ]` |
| `pattern` | `nullOr (listOf str)` | `null` | List of file patterns (globs) to match against (e.g., `*.py`, `*`). If `null`, matches all files for the given event. | `[ "*.lua", "*.nix" ]` |
| `callback` | `nullOr luaInline` | `null` | A Lua function to execute when the event triggers. Use `lib.generators.mkLuaInline`. **Cannot be used with `command`.** | `lib.generators.mkLuaInline "function() print('File saved!') end"` |
| `command` | `nullOr str` | `null` | A Vimscript command to execute when the event triggers. **Cannot be used with `callback`.** | `"echo 'File saved!'"` |
| `group` | `nullOr str` | `null` | The name of an `augroup` (defined in `vim.augroups`) to associate this autocommand with. | `"MyCustomAuGroup"` |
| `desc` | `nullOr str` | `null` | A description for the autocommand (useful for introspection). | `"Format buffer on save"` |
| `once` | `bool` | `false` | If `true`, the autocommand runs only once and then automatically removes itself. | `false` |
| `nested` | `bool` | `false` | If `true`, allows this autocommand to trigger other autocommands. | `false` |
:::{.warning}
You cannot define both `callback` (for Lua functions) and `command` (for
Vimscript) for the same autocommand. Choose one.
:::
**Examples:**
```nix
{ lib, ... }:
{
vim.augroups = [ { name = "UserSetup"; } ];
vim.autocmds = [
# Example 1: Using a Lua callback
{
event = [ "BufWritePost" ];
pattern = [ "*.lua" ];
group = "UserSetup";
desc = "Notify after saving Lua file";
callback = lib.generators.mkLuaInline ''
function()
vim.notify("Lua file saved!", vim.log.levels.INFO)
end
'';
}
# Example 2: Using a Vim command
{
event = [ "FileType" ];
pattern = [ "markdown" ];
group = "UserSetup";
desc = "Set spellcheck for Markdown";
command = "setlocal spell";
}
# Example 3: Autocommand without a specific group
{
event = [ "BufEnter" ];
pattern = [ "*.log" ];
desc = "Disable line numbers in log files";
command = "setlocal nonumber";
# No 'group' specified
}
# Example 4: Using Lua for callback
{
event = [ "BufWinEnter" ];
pattern = [ "*" ];
desc = "Simple greeting on entering a buffer window";
callback = lib.generators.mkLuaInline ''
function(args)
print("Entered buffer: " .. args.buf)
end
'';
# Run only once per session trigger
once = true;
}
];
}
```
These definitions are automatically translated into the necessary Lua code to
configure `vim.api.nvim_create_augroup` and `vim.api.nvim_create_autocmd` when
Neovim starts.

View file

@ -1,53 +0,0 @@
# Custom Inputs {#ch-custom-inputs}
One of the greatest strengths of **nvf** is its ability to get plugins from
flake inputs and build them locally from any given source. For plugins that do
not require any kind of additional building step, this is a powerful method of
adding plugins to your configuration that are not packaged in nixpkgs, or those
you want to track from source without relying on nixpkgs.
The [additional plugins section](#sec-additional-plugins) details the addition
of new plugins to nvf under regular circumstances, i.e. while making a pull
request to the project. You may _override_ those plugin inputs in your own
`flake.nix` to change source versions, e.g., to use newer versions of plugins
that are not yet updated in **nvf**.
```nix
{
inputs = {
# ...
# The name here is arbitrary, you can name it whatever.
# This will add a plugin input called "your-neodev-input"
# that you can reference in a `follows` line.
your-neodev-input = {
url = "github:folke/neodev.nvim";
flake = false;
};
nvf = {
url = "github:notashelf/nvf";
# The name of the input must match for the follows line
# plugin-neodev-nvim is what the input is called inside nvf
# so you must match the exact name here.
inputs.plugin-neodev-nvim.follows = "your-neodev-input";
};
# ...
};
}
```
This will override the source for the `neodev.nvim` plugin that is used in nvf
with your own input. You can update your new input via `nix flake update` or
more specifically `nix flake update <name of your input>` to keep it up to date.
::: {.warning}
While updating plugin inputs, make sure that any configuration that has been
deprecated in newer versions is changed in the plugin's `setupOpts`. If you
depend on a new version, requesting a version bump in the issues section is a
more reliable option.
:::

View file

@ -1,12 +1,12 @@
# Custom Neovim Package {#ch-custom-package}
As of v0.5, you may now specify the Neovim package that will be wrapped with
your configuration. This is done with the `vim.package` option.
your configuration. This is done with the [](#opt-vim.package) option.
```nix
{inputs, pkgs, ...}: {
# using the neovim-nightly overlay
vim.package = inputs.neovim-overlay.packages.${pkgs.system}.neovim;
vim.package = inputs.neovim-overlay.packages.${pkgs.stdenv.system}.neovim;
}
```

View file

@ -1,22 +1,33 @@
# Custom Plugins {#ch-custom-plugins}
**nvf**, by default, exposes a wide variety of plugins as module options for
your convenience and bundles necessary dependencies into **nvf**'s runtime. In
case a plugin is not available in **nvf**, you may consider making a pull
request to **nvf** to include it as a module or you may add it to your
configuration locally.
**nvf** exposes a very wide variety of plugins by default, which are consumed by
module options. This is done for your convenience, and to bundle all necessary
dependencies into **nvf**'s runtime with full control of versioning, testing and
dependencies. In the case a plugin you need is _not_ available, you may consider
making a pull request to add the package you're looking for, or you may add it
to your configuration locally. The below section describes how new plugins may
be added to the user's configuration.
## Adding Plugins {#ch-adding-plugins}
There are multiple ways of adding custom plugins to your **nvf** configuration.
Per **nvf**'s design choices, there are several ways of adding custom plugins to
your configuration as you need them. As we aim for extensive configuration, it
is possible to add custom plugins (from nixpkgs, pinning tools, flake inputs,
etc.) to your Neovim configuration before they are even implemented in **nvf**
as a module.
You can use custom plugins, before they are implemented in the flake. To add a
plugin to the runtime, you need to add it to the [](#opt-vim.startPlugins) list
in your configuration.
:::{.info}
Adding a plugin to `startPlugins` will not allow you to configure the plugin
that you have added, but **nvf** provides multiple way of configuring any custom
plugins that you might have added to your configuration.
To add a plugin to your runtime, you will need to add it to
[](#opt-vim.startPlugins) list in your configuration. This is akin to cloning a
plugin to `~/.config/nvim`, but they are only ever placed in the Nix store and
never exposed to the outside world for purity and full isolation.
:::
As you would configure a cloned plugin, you must configure the new plugins that
you've added to `startPlugins.` **nvf** provides multiple ways of configuring
any custom plugins that you might have added to your configuration.
```{=include=} sections
custom-plugins/configuring.md

View file

@ -1,13 +1,20 @@
# Configuring {#sec-configuring-plugins}
Just making the plugin to your Neovim configuration available might not always
be enough. In that case, you can write custom lua config using either
`config.vim.lazy.plugins.*.setupOpts` `config.vim.extraPlugins.*.setup` or
`config.vim.luaConfigRC`.
be enough., for example, if the plugin requires a setup table. In that case, you
can write custom Lua configuration using one of
The first option uses an extended version of `lz.n`'s PluginSpec. `setupModule`
and `setupOpt` can be used if the plugin uses a `require('module').setup(...)`
pattern. Otherwise, the `before` and `after` hooks should do what you need.
- `config.vim.lazy.plugins.*.setupOpts`
- `config.vim.extraPlugins.*.setup`
- `config.vim.luaConfigRC`.
## Lazy Plugins {#ch-vim-lazy-plugins}
`config.vim.lazy.plugins.*.setupOpts` is useful for lazy-loading plugins, and
uses an extended version of `lz.n's` `PluginSpec` to expose a familiar
interface. `setupModule` and `setupOpt` can be used if the plugin uses a
`require('module').setup(...)` pattern. Otherwise, the `before` and `after`
hooks should do what you need.
```nix
{
@ -25,50 +32,61 @@ pattern. Otherwise, the `before` and `after` hooks should do what you need.
}
```
The second option uses an attribute set, which maps DAG section names to a
## Standard API {#ch-vim-extra-plugins}
`vim.extraPlugins` uses an attribute set, which maps DAG section names to a
custom type, which has the fields `package`, `after`, `setup`. They allow you to
set the package of the plugin, the sections its setup code should be after (note
that the `extraPlugins` option has its own DAG scope), and the its setup code
respectively. For example:
```nix
config.vim.extraPlugins = with pkgs.vimPlugins; {
aerial = {
package = aerial-nvim;
setup = "require('aerial').setup {}";
};
{pkgs, ...}: {
config.vim.extraPlugins = {
aerial = {
package = pkgs.vimPlugins.aerial-nvim;
setup = "require('aerial').setup {}";
};
harpoon = {
package = harpoon;
setup = "require('harpoon').setup {}";
after = ["aerial"]; # place harpoon configuration after aerial
harpoon = {
package = pkgs.vimPlugins.harpoon;
setup = "require('harpoon').setup {}";
after = ["aerial"]; # place harpoon configuration after aerial
};
};
}
```
The third option also uses an attribute set, but this one is resolved as a DAG
### Setup using luaConfigRC {#setup-using-luaconfigrc}
`vim.luaConfigRC` also uses an attribute set, but this one is resolved as a DAG
directly. The attribute names denote the section names, and the values lua code.
For example:
```nix
{
# this will create an "aquarium" section in your init.lua with the contents of your custom config
# which will be *appended* to the rest of your configuration, inside your init.vim
# This will create a section called "aquarium" in the 'init.lua' with the
# contents of your custom configuration. By default 'entryAnywhere' is implied
# in DAGs, so this will be inserted to an arbitrary position. In the case you
# wish to control the position of this section with more precision, please
# look into the DAGs section of the manual.
config.vim.luaConfigRC.aquarium = "vim.cmd('colorscheme aquiarum')";
}
```
<!-- deno-fmt-ignore-start -->
[DAG system]: #ch-using-dags
[DAG section]: #ch-dag-entries
::: {.note}
One of the greatest strengths of nvf is the ability to order
snippets of configuration via the DAG system. It will allow specifying positions
of individual sections of configuration as needed. nvf provides helper functions
One of the **greatest strengths** of **nvf** is the ability to order
configuration snippets precisely using the [DAG system]. DAGs
are a very powerful mechanism that allows specifying positions
of individual sections of configuration as needed. We provide helper functions
in the extended library, usually under `inputs.nvf.lib.nvim.dag` that you may
use.
Please refer to the [DAG section](/index.xhtml#ch-dag-entries) in the nvf manual
Please refer to the [DAG section] in the nvf manual
to find out more about the DAG system.
:::
<!-- deno-fmt-ignore-end -->

View file

@ -1,7 +1,8 @@
# Lazy Method {#sec-lazy-method}
As of version **0.7**, we exposed an API for configuring lazy-loaded plugins via
`lz.n` and `lzn-auto-require`.
As of version **0.7**, an API is exposed to allow configuring lazy-loaded
plugins via `lz.n` and `lzn-auto-require`. Below is a comprehensive example of
how it may be loaded to lazy-load an arbitrary plugin.
```nix
{
@ -38,3 +39,24 @@ As of version **0.7**, we exposed an API for configuring lazy-loaded plugins via
};
}
```
## LazyFile event {#sec-lazyfile-event}
**nvf** re-implements `LazyFile` as a familiar user event to load a plugin when
a file is opened:
```nix
{
config.vim.lazy.plugins = {
"aerial.nvim" = {
package = pkgs.vimPlugins.aerial-nvim;
event = [{event = "User"; pattern = "LazyFile";}];
# ...
};
};
}
```
You can consider the `LazyFile` event as an alias to the combination of
`"BufReadPost"`, `"BufNewFile"` and `"BufWritePre"`, i.e., a list containing all
three of those events: `["BufReadPost" "BufNewFile" "BufWritePre"]`

View file

@ -1,26 +1,31 @@
# Legacy Method {#sec-legacy-method}
Prior to version v0.5, the method of adding new plugins was adding the plugin
package to `vim.startPlugins` and add its configuration as a DAG under one of
`vim.configRC` or `vim.luaConfigRC`. Users who have not yet updated to 0.5, or
prefer a more hands-on approach may use the old method where the load order of
the plugins is determined by DAGs.
Prior to version **0.5**, the method of adding new plugins was adding the plugin
package to [](#opt-vim.startPlugins) and adding its configuration as a DAG under
one of `vim.configRC` or [](#opt-vim.luaConfigRC). While `configRC` has been
deprecated, users who have not yet updated to 0.5 or those who prefer a more
hands-on approach may choose to use the old method where the load order of the
plugins is explicitly determined by DAGs without internal abstractions.
## Adding plugins {#sec-adding-plugins}
## Adding New Plugins {#sec-adding-new-plugins}
To add a plugin not available in nvf as a module to your configuration, you may
add it to [](#opt-vim.startPlugins) in order to make it available to Neovim at
runtime.
To add a plugin not available in **nvf** as a module to your configuration using
the legacy method, you must add it to [](#opt-vim.startPlugins) in order to make
it available to Neovim at runtime.
```nix
{pkgs, ...}: {
# Add a Neovim plugin from Nixpkgs to the runtime.
# This does not need to come explicitly from packages. 'vim.startPlugins'
# takes a list of *string* (to load internal plugins) or *package* to load
# a Neovim package from any source.
vim.startPlugins = [pkgs.vimPlugins.aerial-nvim];
}
```
And to configure the added plugin, you can use the `luaConfigRC` option to
provide configuration as a DAG using the **nvf** extended library.
Once the package is available in Neovim's runtime, you may use the `luaConfigRC`
option to provide configuration as a DAG using the **nvf** extended library in
order to configure the added plugin,
```nix
{inputs, ...}: let
@ -29,6 +34,8 @@ provide configuration as a DAG using the **nvf** extended library.
# to specialArgs, the 'inputs' prefix may be omitted.
inherit (inputs.nvf.lib.nvim.dag) entryAnywhere;
in {
# luaConfigRC takes Lua configuration verbatim and inserts it at an arbitrary
# position by default or if 'entryAnywhere' is used.
vim.luaConfigRC.aerial-nvim= entryAnywhere ''
require('aerial').setup {
-- your configuration here

View file

@ -1,14 +1,15 @@
# Non-lazy Method {#sec-non-lazy-method}
As of version **0.5**, we have a more extensive API for configuring plugins,
under `vim.extraPlugins`. Instead of using DAGs exposed by the library, you may
use the extra plugin module as follows:
As of version **0.5**, we have a more extensive API for configuring plugins that
should be preferred over the legacy method. This API is available as
[](#opt-vim.extraPlugins). Instead of using DAGs exposed by the library
_directly_, you may use the extra plugin module as follows:
```nix
{
config.vim.extraPlugins = with pkgs.vimPlugins; {
{pkgs, ...}: {
config.vim.extraPlugins = {
aerial = {
package = aerial-nvim;
package = pkgs.vimPlugins.aerial-nvim;
setup = ''
require('aerial').setup {
-- some lua configuration here
@ -17,10 +18,12 @@ use the extra plugin module as follows:
};
harpoon = {
package = harpoon;
package = pkgs.vimPlugins.harpoon;
setup = "require('harpoon').setup {}";
after = ["aerial"];
};
};
}
```
This provides a level of abstraction over the DAG system for faster iteration.

View file

@ -14,14 +14,17 @@ explains in more detail the overall usage logic of the DAG type.
## entryAnywhere {#sec-types-dag-entryAnywhere}
> `lib.dag.entryAnywhere (value: T) : DagEntry<T>`
> `nvf.lib.nvim.dag.entryAnywhere (value: T) : DagEntry<T>`
Indicates that `value` can be placed anywhere within the DAG. This is also the
default for plain attribute set entries, that is
```nix
# For 'nvf' to be available in module's arguments,
# it needs to be inherited from imports in the modules array as:
# modules = [{ _module.args = { inherit nvf; }; } ...];
foo.bar = {
a = lib.dag.entryAnywhere 0;
a = nvf.lib.nvim.dag.entryAnywhere 0;
}
```
@ -37,7 +40,7 @@ are equivalent.
## entryAfter {#ch-types-dag-entryAfter}
> `lib.dag.entryAfter (afters: list string) (value: T) : DagEntry<T>`
> `nvf.lib.nvim.dag.entryAfter (afters: list string) (value: T) : DagEntry<T>`
Indicates that `value` must be placed _after_ each of the attribute names in the
given list. For example
@ -45,7 +48,7 @@ given list. For example
```nix
foo.bar = {
a = 0;
b = lib.dag.entryAfter [ "a" ] 1;
b = nvf.lib.nvim.dag.entryAfter [ "a" ] 1;
}
```
@ -53,14 +56,14 @@ would place `b` after `a` in the graph.
## entryBefore {#ch-types-dag-entryBefore}
> `lib.dag.entryBefore (befores: list string) (value: T) : DagEntry<T>`
> `nvf.lib.nvim.dag.entryBefore (befores: list string) (value: T) : DagEntry<T>`
Indicates that `value` must be placed _before_ each of the attribute names in
the given list. For example
```nix
foo.bar = {
b = lib.dag.entryBefore [ "a" ] 1;
b = nvf.lib.nvim.dag.entryBefore [ "a" ] 1;
a = 0;
}
```
@ -69,7 +72,7 @@ would place `b` before `a` in the graph.
## entryBetween {#sec-types-dag-entryBetween}
> `lib.dag.entryBetween (befores: list string) (afters: list string) (value: T) : DagEntry<T>`
> `nvf.lib.nvim.dag.entryBetween (befores: list string) (afters: list string) (value: T) : DagEntry<T>`
Indicates that `value` must be placed _before_ the attribute names in the first
list and _after_ the attribute names in the second list. For example
@ -77,7 +80,7 @@ list and _after_ the attribute names in the second list. For example
```nix
foo.bar = {
a = 0;
c = lib.dag.entryBetween [ "b" ] [ "a" ] 2;
c = nvf.lib.nvim.dag.entryBetween [ "b" ] [ "a" ] 2;
b = 1;
}
```
@ -92,13 +95,13 @@ functions take a `tag` as argument and the DAG entries will be named
## entriesAnywhere {#sec-types-dag-entriesAnywhere}
> `lib.dag.entriesAnywhere (tag: string) (values: [T]) : Dag<T>`
> `nvf.lib.nvim.dag.entriesAnywhere (tag: string) (values: [T]) : Dag<T>`
Creates a DAG with the given values with each entry labeled using the given tag.
For example
```nix
foo.bar = lib.dag.entriesAnywhere "a" [ 0 1 ];
foo.bar = nvf.lib.nvim.dag.entriesAnywhere "a" [ 0 1 ];
```
is equivalent to
@ -106,13 +109,13 @@ is equivalent to
```nix
foo.bar = {
a-0 = 0;
a-1 = lib.dag.entryAfter [ "a-0" ] 1;
a-1 = nvf.lib.nvim.dag.entryAfter [ "a-0" ] 1;
}
```
## entriesAfter {#sec-types-dag-entriesAfter}
> `lib.dag.entriesAfter (tag: string) (afters: list string) (values: [T]) : Dag<T>`
> `nvf.lib.nvim.dag.entriesAfter (tag: string) (afters: list string) (values: [T]) : Dag<T>`
Creates a DAG with the given values with each entry labeled using the given tag.
The list of values are placed are placed _after_ each of the attribute names in
@ -120,7 +123,7 @@ The list of values are placed are placed _after_ each of the attribute names in
```nix
foo.bar =
{ b = 0; } // lib.dag.entriesAfter "a" [ "b" ] [ 1 2 ];
{ b = 0; } // nvf.lib.nvim.dag.entriesAfter "a" [ "b" ] [ 1 2 ];
```
is equivalent to
@ -128,14 +131,14 @@ is equivalent to
```nix
foo.bar = {
b = 0;
a-0 = lib.dag.entryAfter [ "b" ] 1;
a-1 = lib.dag.entryAfter [ "a-0" ] 2;
a-0 = nvf.lib.nvim.dag.entryAfter [ "b" ] 1;
a-1 = nvf.lib.nvim.dag.entryAfter [ "a-0" ] 2;
}
```
## entriesBefore {#sec-types-dag-entriesBefore}
> `lib.dag.entriesBefore (tag: string) (befores: list string) (values: [T]) : Dag<T>`
> `nvf.lib.nvim.dag.entriesBefore (tag: string) (befores: list string) (values: [T]) : Dag<T>`
Creates a DAG with the given values with each entry labeled using the given tag.
The list of values are placed _before_ each of the attribute names in `befores`.
@ -143,7 +146,7 @@ For example
```nix
foo.bar =
{ b = 0; } // lib.dag.entriesBefore "a" [ "b" ] [ 1 2 ];
{ b = 0; } // nvf.lib.nvim.dag.entriesBefore "a" [ "b" ] [ 1 2 ];
```
is equivalent to
@ -152,13 +155,13 @@ is equivalent to
foo.bar = {
b = 0;
a-0 = 1;
a-1 = lib.dag.entryBetween [ "b" ] [ "a-0" ] 2;
a-1 = nvf.lib.nvim.dag.entryBetween [ "b" ] [ "a-0" ] 2;
}
```
## entriesBetween {#sec-types-dag-entriesBetween}
> `lib.dag.entriesBetween (tag: string) (befores: list string) (afters: list string) (values: [T]) : Dag<T>`
> `nvf.lib.nvim.dag.entriesBetween (tag: string) (befores: list string) (afters: list string) (values: [T]) : Dag<T>`
Creates a DAG with the given values with each entry labeled using the given tag.
The list of values are placed _before_ each of the attribute names in `befores`
@ -166,7 +169,7 @@ and _after_ each of the attribute names in `afters`. For example
```nix
foo.bar =
{ b = 0; c = 3; } // lib.dag.entriesBetween "a" [ "b" ] [ "c" ] [ 1 2 ];
{ b = 0; c = 3; } // nvf.lib.nvim.dag.entriesBetween "a" [ "b" ] [ "c" ] [ 1 2 ];
```
is equivalent to
@ -175,7 +178,7 @@ is equivalent to
foo.bar = {
b = 0;
c = 3;
a-0 = lib.dag.entryAfter [ "c" ] 1;
a-1 = lib.dag.entryBetween [ "b" ] [ "a-0" ] 2;
a-0 = nvf.lib.nvim.dag.entryAfter [ "c" ] 1;
a-1 = nvf.lib.nvim.dag.entryBetween [ "b" ] [ "a-0" ] 2;
}
```

View file

@ -19,6 +19,7 @@ formatting to diagnostics. The following languages have sections under the
- Go: [vim.languages.go.enable](#opt-vim.languages.go.enable)
- Lua: [vim.languages.lua.enable](#opt-vim.languages.lua.enable)
- PHP: [vim.languages.php.enable](#opt-vim.languages.php.enable)
- F#: [vim.languages.fsharp.enable](#opt-vim.languages.fsharp.enable)
Adding support for more languages, and improving support for existing ones are
great places where you can contribute with a PR.

View file

@ -1,17 +1,22 @@
# LSP Custom Packages/Command {#sec-languages-custom-lsp-packages}
In any of the `opt.languages.<language>.lsp.package` options you can provide
your own LSP package, or provide the command to launch the language server, as a
list of strings. You can use this to skip automatic installation of a language
server, and instead use the one found in your `$PATH` during runtime, for
example:
One of the strengths of **nvf** is convenient aliases to quickly configure LSP
servers through the Nix module system. By default the LSP packages for relevant
language modules will be pulled into the closure. If this is not desirable, you
may provide **a custom LSP package** (e.g., a Bash script that calls a command)
or **a list of strings** to be interpreted as the command to launch the language
server. By using a list of strings, you can use this to skip automatic
installation of a language server, and instead use the one found in your `$PATH`
during runtime, for example:
```nix
vim.languages.java = {
lsp = {
enable = true;
# this expects jdt-language-server to be in your PATH
# or in `vim.extraPackages`
# This expects 'jdt-language-server' to be in your PATH or in
# 'vim.extraPackages.' There are no additional checks performed to see
# if the command provided is valid.
package = ["jdt-language-server" "-data" "~/.cache/jdtls/workspace"];
};
}

View file

@ -0,0 +1,35 @@
# Overriding plugins {#ch-overriding-plugins}
The [additional plugins section](#sec-additional-plugins) details the addition
of new plugins to nvf under regular circumstances, i.e. while making a pull
request to the project. You may _override_ those plugins in your config to
change source versions, e.g., to use newer versions of plugins that are not yet
updated in **nvf**.
```nix
vim.pluginOverrides = {
lazydev-nvim = pkgs.fetchFromGitHub {
owner = "folke";
repo = "lazydev.nvim";
rev = "";
hash = "";
};
# It's also possible to use a flake input
lazydev-nvim = inputs.lazydev-nvim;
# Or a local path
lazydev-nvim = ./lazydev;
# Or a npins pin... etc
};
```
This will override the source for the `neodev.nvim` plugin that is used in nvf
with your own plugin.
::: {.warning}
While updating plugin inputs, make sure that any configuration that has been
deprecated in newer versions is changed in the plugin's `setupOpts`. If you
depend on a new version, requesting a version bump in the issues section is a
more reliable option.
:::

View file

@ -1,10 +0,0 @@
# Default Configs {#ch-default-configs}
While you can configure **nvf** yourself using the builder, you can also use the
pre-built configs that are available. Here are a few default configurations you
can use.
```{=include=} chapters
default-configs/maximal.md
default-configs/nix.md
```

View file

@ -1,11 +0,0 @@
# Maximal {#sec-default-maximal}
```bash
$ nix shell github:notashelf/nvf#maximal test.nix
```
It is the same fully configured Neovim as with the [Nix](#sec-default-nix)
configuration, but with every supported language enabled.
::: {.note} Running the maximal config will download _a lot_ of packages as it
is downloading language servers, formatters, and more. :::

View file

@ -1,9 +0,0 @@
# Nix {#sec-default-nix}
```bash
$ nix run github:notashelf/nvf#nix test.nix
```
Enables all the of Neovim plugins, with language support for specifically Nix.
This lets you see what a fully configured neovim setup looks like without
downloading a whole bunch of language servers and associated tools.

View file

@ -1,36 +1,92 @@
# Adding Plugins {#sec-additional-plugins}
To add a new Neovim plugin, first add the source url in the inputs section of
`flake.nix` with the prefix `plugin-`
There are two methods for adding new Neovim plugins to **nvf**. npins is the
faster option that should be preferred if the plugin consists of pure Lua or
Vimscript code. In which case there is no building required, and we can easily
handle the copying of plugin files. Alternative method, which is required when
plugins try to build their own libraries (e.g., in Rust or C) that need to be
built with Nix to function correctly.
## With npins {#sec-npins-for-plugins}
npins is the standard method of adding new plugins to **nvf**. You simply need
the repository URL for the plugin, and can add it as a source to be built
automatically with one command. To add a new Neovim plugin, use `npins`. For
example:
```bash
nix-shell -p npins # or nix shell nixpkgs#npins if using flakes
```
Then run:
```bash
npins add --name <plugin name> github <owner> <repo> -b <branch>
```
::: {.note}
Be sure to replace any non-alphanumeric characters with `-` for `--name`. For
example
```bash
npins add --name lazydev-nvim github folke lazydev.nvim -b main
```
:::
Once the `npins` command is done, you can start referencing the plugin as a
**string**.
```nix
{
inputs = {
# ...
plugin-neodev-nvim = {
url = "github:folke/neodev.nvim";
flake = false;
};
# ...
};
config.vim.startPlugins = ["lazydev-nvim"];
}
```
Prepending `plugin-` to the name of the input will allow nvf to automatically
discover inputs that are marked as plugins, and make them available in
`vim.startPlugins` or other areas that require a very specific plugin type as it
is defined in `@NVF_REPO@/lib/types/plugins.nix`
## Packaging Complex Plugins {#sec-pkgs-for-plugins}
The addition of the `plugin-` prefix will allow **nvf** to autodiscover the
input from the flake inputs automatically, allowing you to refer to it in areas
that require a very specific plugin type as defined in `lib/types/plugins.nix`
[blink.cmp]: https://github.com/Saghen/blink.cmp
You can now reference this plugin using its string name, the plugin will be
built with the name and source URL from the flake input, allowing you to refer
to it as a **string**.
Some plugins require additional packages to be built and substituted to function
correctly. For example [blink.cmp] requires its own fuzzy matcher library, built
with Rust, to be installed or else defaults to a much slower Lua implementation.
In the Blink documentation, you are advised to build with `cargo` but that is
not ideal since we are leveraging the power of Nix. In this case the ideal
solution is to write a derivation for the plugin.
We use `buildRustPackage` to build the library from the repository root, and
copy everything in the `postInstall` phase.
```nix
config.vim.startPlugins = ["neodev-nvim"];
postInstall = ''
cp -r {lua,plugin} "$out"
mkdir -p "$out/doc"
cp 'doc/'*'.txt' "$out/doc/"
mkdir -p "$out/target"
mv "$out/lib" "$out/target/release"
'';
```
In a similar fashion, you may utilize `stdenv.mkDerivation` and other Nixpkgs
builders to build your library from source, and copy the relevant files and Lua
plugin files in the `postInstall` phase. Do note, however, that you still need
to fetch the plugin sources somehow. npins is, once again, the recommended
option to fetch the plugin sources. Refer to the previous section on how to use
npins to add a new plugin.
Plugins built from source must go into the `flake/pkgs/by-name` overlay. It will
automatically create flake outputs for individual packages. Lastly, you must add
your package to the plugin builder (`pluginBuilders`) function manually in
`modules/wrapper/build/config.nix`. Once done, you may refer to your plugin as a
**string**.
```nix
{
config.vim.startPlugins = ["blink-cmp"];
}
```
## Modular setup options {#sec-modular-setup-options}
@ -81,7 +137,7 @@ in {
}
```
This above config will result in this lua script:
This above config will result in this Lua script:
```lua
require('plugin-name').setup({
@ -112,23 +168,41 @@ own fields!
As you've seen above, `toLuaObject` is used to convert our nix attrSet
`cfg.setupOpts`, into a lua table. Here are some rules of the conversion:
1. nix `null` converts to lua `nil`
2. number and strings convert to their lua counterparts
3. nix attrSet/list convert into lua tables
4. you can write raw lua code using `lib.generators.mkLuaInline`. This function
is part of nixpkgs.
1. Nix `null` converts to lua `nil`
2. Number and strings convert to their lua counterparts
3. Nix attribute sets (`{}`) and lists (`[]`) convert into Lua dictionaries and
tables respectively. Here is an example of Nix -> Lua conversion.
- `{foo = "bar"}` -> `{["foo"] = "bar"}`
- `["foo" "bar"]` -> `{"foo", "bar"}`
4. You can write raw Lua code using `lib.generators.mkLuaInline`. This function
is part of nixpkgs, and is accessible without relying on **nvf**'s extended
library.
- `mkLuaInline "function add(a, b) return a + b end"` will yield the
following result:
Example:
```nix
{
_type = "lua-inline";
expr = "function add(a, b) return a + b end";
}
```
```nix
vim.your-plugin.setupOpts = {
on_init = lib.generators.mkLuaInline ''
function()
print('we can write lua!')
end
'';
}
```
The above expression will be interpreted as a Lua expression in the final
config. Without the `mkLuaInline` function, you will only receive a string
literal. You can use it to feed plugin configuration tables Lua functions
that return specific values as expected by the plugins.
```nix
{
vim.your-plugin.setupOpts = {
on_init = lib.generators.mkLuaInline ''
function()
print('we can write lua!')
end
'';
};
}
```
## Lazy plugins {#sec-lazy-plugins}
@ -137,25 +211,24 @@ Lazy plugins are managed by `lz.n`.
```nix
# in modules/.../your-plugin/config.nix
{lib, config, ...}:
let
{config, ...}: let
cfg = config.vim.your-plugin;
in {
vim.lazy.plugins.your-plugin = {
# instead of vim.startPlugins, use this:
# Instead of vim.startPlugins, use this:
package = "your-plugin";
# if your plugin uses the `require('your-plugin').setup{...}` pattern
# ıf your plugin uses the `require('your-plugin').setup{...}` pattern
setupModule = "your-plugin";
inherit (cfg) setupOpts;
# events that trigger this plugin to be loaded
# Events that trigger this plugin to be loaded
event = ["DirChanged"];
cmd = ["YourPluginCommand"];
# keymaps
# Plugin Keymaps
keys = [
# we'll cover this in detail in the keymaps section
# We'll cover this in detail in the 'keybinds' section
{
key = "<leader>d";
mode = "n";
@ -163,7 +236,6 @@ in {
}
];
};
;
}
```
@ -174,7 +246,9 @@ require('lz.n').load({
{
"name-of-your-plugin",
after = function()
require('your-plugin').setup({--[[ your setupOpts ]]})
require('your-plugin').setup({
--[[ your setupOpts ]]--
})
end,
event = {"DirChanged"},
@ -186,5 +260,7 @@ require('lz.n').load({
})
```
A full list of options can be found
[here](https://notashelf.github.io/nvf/options.html#opt-vim.lazy.plugins
[`vim.lazy.plugins` spec]: https://notashelf.github.io/nvf/options.html#opt-vim.lazy.plugins
A full list of options can be found in the [`vim.lazy.plugins` spec] on the
rendered manual.

View file

@ -30,8 +30,8 @@ There are many settings available in the options. Please refer to the
[documentation](https://notashelf.github.io/nvf/options.html#opt-vim.keymaps) to
see a list of them.
**nvf** provides a helper function, so that you don't have to write the
mapping attribute sets every time:
**nvf** provides a helper function, so that you don't have to write the mapping
attribute sets every time:
- `mkKeymap`, which mimics neovim's `vim.keymap.set` function

View file

@ -23,34 +23,32 @@ An example flake that exposes your custom Neovim configuration might look like
nvf.url = "github:notashelf/nvf";
};
outputs = {
self,
nixpkgs,
...
} @ inputs: {
packages."x86_64-linux" = let
neovimConfigured = (inputs.nvf.lib.neovimConfiguration {
inherit (nixpkgs.legacyPackages."x86_64-linux") pkgs;
modules = [{
outputs = {nixpkgs, ...} @ inputs: {
packages.x86_64-linux = {
# Set the default package to the wrapped instance of Neovim.
# This will allow running your Neovim configuration with
# `nix run` and in addition, sharing your configuration with
# other users in case your repository is public.
default =
(inputs.nvf.lib.neovimConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
{
config.vim = {
# Enable custom theming options
theme.enable = true;
# Enable Treesitter
tree-sitter.enable = true;
treesitter.enable = true;
# Other options will go here. Refer to the config
# reference in Appendix B of the nvf manual.
# ...
};
}];
});
in {
# Set the default package to the wrapped instance of Neovim.
# This will allow running your Neovim configuration with
# `nix run` and in addition, sharing your configuration with
# other users in case your repository is public.
default = neovimConfigured.neovim;
}
];
})
.neovim;
};
};
}

View file

@ -0,0 +1,33 @@
### Prerequisites {#sec-flakes-prerequisites}
To install nvf with flakes, you must make sure the following requirements are
met.
1. Nix 2.4 or later must be installed. You may use `nix-shell` to get a later
version of Nix from nixpkgs.
2. Flake-related experimental features must be enabled. Namely, you need
`nix-command` and `flakes`. Some Nix vendors enable those by default, please
consult their documentation if you are not using mainstream Nix.
- When using NixOS, add the following to your `configuration.nix` and rebuild
your system.
```nix
nix.settings.experimental-features = "nix-command flakes";
```
- If you are not using NixOS, add the following to `nix.conf` (located at
`~/.config/nix/` or `/etc/nix/nix.conf`).
```bash
experimental-features = nix-command flakes
```
- You may need to restart the Nix daemon with, for example,
`sudo systemctl restart nix-daemon.service`.
- Alternatively, you can enable flakes on a per-command basis with the
following additional flags to `nix` and `home-manager`:
```sh
$ nix --extra-experimental-features "nix-command flakes" <sub-commands>
```

View file

@ -5,9 +5,18 @@ inside the home-manager configuration without having to call for the wrapper
yourself. It is the recommended way to use **nvf** alongside the NixOS module
depending on your needs.
To use it, we first add the input flake.
## With Flakes {#sec-hm-flakes}
```{=include=}
flakes.md
```
### Usage {#sec-hm-flakes-usage}
To use **nvf** with flakes, we first need to add the input to our `flake.nix`.
```nix
# flake.nix
{
inputs = {
# Optional, if you intend to follow nvf's obsidian-nvim input
@ -16,7 +25,7 @@ To use it, we first add the input flake.
# Required, nvf works best and only directly supports flakes
nvf = {
url = "github:notashelf/nvf";
url = "github:NotAShelf/nvf";
# You can override the input nixpkgs to follow your system's
# instance of nixpkgs. This is safe to do as nvf does not depend
# on a binary cache.
@ -25,6 +34,8 @@ To use it, we first add the input flake.
# for example:
inputs.obsidian-nvim.follows = "obsidian-nvim"; # <- this will use the obsidian-nvim from your inputs
};
# ...
};
}
```
@ -39,7 +50,7 @@ Followed by importing the home-manager module somewhere in your configuration.
}
```
## Example Installation {#sec-example-installation-hm}
### Example Installation {#sec-example-installation-hm}
```nix
{
@ -49,13 +60,10 @@ Followed by importing the home-manager module somewhere in your configuration.
nvf.url = "github:notashelf/nvf";
};
outputs = { nixpkgs, home-manager, nvf, ... }: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
outputs = { nixpkgs, home-manager, nvf, ... }: {
# ↓ this is your home output in the flake schema, expected by home-manager
"your-username@your-hostname" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
nvf.homeManagerModules.default # <- this imports the home-manager module that provides the options
./home.nix # <- your home entrypoint, `programs.nvf.*` may be defined here
@ -69,7 +77,8 @@ Once the module is properly imported by your host, you will be able to use the
`programs.nvf` module option anywhere in your configuration in order to
configure **nvf**.
```nix{
```nix
{
programs.nvf = {
enable = true;
# your settings need to go into the settings attribute set
@ -92,3 +101,45 @@ installation sections of the manual. You may find all available options in the
[appendix](https://notashelf.github.io/nvf/options)
:::
## Without Flakes {#sec-hm-flakeless}
As of v0.8, it is possible to install **nvf** on a system if you are not using
flakes. This is possible thanks to the flake-compat project.
To get started, you must fetch the repository using `builtins.fetchTarball` or a
similar mechanism.
```nix
# home.nix
let
nvf = import (builtins.fetchTarball {
url = "https://github.com/notashelf/nvf/archive/<commit or tag>.tar.gz";
# Optionally, you can add 'sha256' for verification and caching
# sha256 = "<sha256>";
});
in {
imports = [
# Import the NixOS module from your fetched input
nvf.homeManagerModules.nvf
];
# Once the module is imported, you may use `programs.nvf` as exposed by the
# NixOS module.
programs.nvf.enable = true;
}
```
[npins]: https://github.com/andir/npins
[niv]: https://github.com/nmattia/niv
::: {.tip}
Nix2 does not have a builtin lockfile mechanism like flakes. As such you must
manually update the URL and hash for your input. This is annoying to deal with,
and most users choose to defer this task to projects such as [npins] or [niv].
If you are new to NixOS, I encourage you to look into Flakes and see if they fit
your use case. Alternatively, look into the aforementioned projects for more
convenient dependency management mechanisms.
:::

View file

@ -5,9 +5,18 @@ the NixOS configuration without having to call for the wrapper yourself. It is
the recommended way to use **nvf** alongside the home-manager module depending
on your needs.
To use it, we first add the input flake.
## With Flakes {#sec-nixos-flakes}
```{=include=}
flakes.md
```
### Usage {#sec-nixos-flakes-usage}
To use **nvf** with flakes, we first need to add the input to our `flake.nix`.
```nix
# flake.nix
{
inputs = {
# Optional, if you intend to follow nvf's obsidian-nvim input
@ -16,7 +25,7 @@ To use it, we first add the input flake.
# Required, nvf works best and only directly supports flakes
nvf = {
url = "github:notashelf/nvf";
url = "github:NotAShelf/nvf";
# You can override the input nixpkgs to follow your system's
# instance of nixpkgs. This is safe to do as nvf does not depend
# on a binary cache.
@ -25,6 +34,8 @@ To use it, we first add the input flake.
# for example:
inputs.obsidian-nvim.follows = "obsidian-nvim"; # <- this will use the obsidian-nvim from your inputs
};
# ...
};
}
```
@ -39,7 +50,7 @@ Followed by importing the NixOS module somewhere in your configuration.
}
```
## Example Installation {#sec-example-installation-nixos}
### Example Installation {#sec-example-installation-nixos}
```nix
{
@ -64,10 +75,12 @@ Once the module is properly imported by your host, you will be able to use the
`programs.nvf` module option anywhere in your configuration in order to
configure **nvf**.
```nix{
```nix
{
programs.nvf = {
enable = true;
# your settings need to go into the settings attribute set
# Your settings need to go into the settings attribute set
# most settings are documented in the appendix
settings = {
vim.viAlias = false;
@ -87,3 +100,45 @@ installation sections of the manual. You may find all available options in the
[appendix](https://notashelf.github.io/nvf/options)
:::
## Without Flakes {#sec-nixos-flakeless}
As of v0.8, it is possible to install **nvf** on a system if you are not using
flakes. This is possible thanks to the flake-compat project.
To get started, you must fetch the repository using `builtins.fetchTarball` or a
similar mechanism.
```nix
# configuration.nix
let
nvf = import (builtins.fetchTarball {
url = "https://github.com/notashelf/nvf/archive/<commit or tag>.tar.gz";
# Optionally, you can add 'sha256' for verification and caching
# sha256 = "<sha256>";
});
in {
imports = [
# Import the NixOS module from your fetched input
nvf.nixosModules.nvf
];
# Once the module is imported, you may use `programs.nvf` as exposed by the
# NixOS module.
programs.nvf.enable = true;
}
```
[npins]: https://github.com/andir/npins
[niv]: https://github.com/nmattia/niv
::: {.tip}
Nix2 does not have a builtin lockfile mechanism like flakes. As such you must
manually update the URL and hash for your input. This is annoying to deal with,
and most users choose to defer this task to projects such as [npins] or [niv].
If you are new to NixOS, I encourage you to look into Flakes and see if they fit
your use case. Alternatively, look into the aforementioned projects for more
convenient dependency management mechanisms.
:::

View file

@ -16,26 +16,32 @@ the default theme enabled. You may use other options inside `config.vim` in
nvf.url = "github:notashelf/nvf";
};
outputs = {nixpkgs, nvf, ...}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
configModule = {
# Add any custom options (and do feel free to upstream them!)
# options = { ... };
config.vim = {
theme.enable = true;
# and more options as you see fit...
};
};
customNeovim = nvf.lib.neovimConfiguration {
inherit pkgs;
modules = [configModule];
};
in {
outputs = {
nixpkgs,
nvf,
self,
...
}: {
# This will make the package available as a flake output under 'packages'
packages.${system}.my-neovim = customNeovim.neovim;
packages.x86_64-linux.my-neovim =
(nvf.lib.neovimConfiguration {
pkgs = nixpkgs.legacyPackages.x86_64-linux;
modules = [
# Or move this to a separate file and add it's path here instead
# IE: ./nvf_module.nix
(
{pkgs, ...}: {
# Add any custom options (and do feel free to upstream them!)
# options = { ... };
config.vim = {
theme.enable = true;
# and more options as you see fit...
};
}
)
];
})
.neovim;
# Example nixosConfiguration using the configured Neovim package
nixosConfigurations = {
@ -43,7 +49,11 @@ the default theme enabled. You may use other options inside `config.vim` in
# ...
modules = [
# This will make wrapped neovim available in your system packages
{environment.systemPackages = [customNeovim.neovim];}
# Can also move this to another config file if you pass your own
# inputs/self around with specialArgs
({pkgs, ...}: {
environment.systemPackages = [self.packages.${pkgs.stdenv.system}.neovim];
})
];
# ...
};

View file

@ -8,7 +8,6 @@ try-it-out.md
```
```{=include=} parts
default-configs.md
installation.md
configuring.md
tips.md

View file

@ -1,9 +1,13 @@
# Neovim Flake Configuration Options {#ch-options}
# nvf Configuration Options {#ch-options}
Below are the module options provided by nvf, in no particular order. Most
options will include useful comments, warnings or setup tips on how a module
option is meant to be used as well as examples in complex cases.
An offline version of this page is bundled with nvf as a part of the manpages
which you can access with `man 5 nvf`. Please let us know if you believe any of
the options below are missing useful examples.
<!--
In the manual, individual options may be referenced in Hyperlinks as follows:
[](#opt-vim.*) If changing the prefix here, do keep in mind the #opt- suffix will have

View file

@ -1,6 +1,14 @@
# Helpful Tips {#ch-helpful-tips}
This section provides helpful tips that may be considered "unorthodox" or "too
advanced" for some users. We will cover basic debugging steps, offline
documentation, configuring **nvf** with pure Lua and using custom plugin sources
in **nvf** in this section. For general configuration tips, please see previous
chapters.
```{=include=} chapters
tips/debugging-nvf.md
tips/offline-docs.md
tips/pure-lua-config.md
tips/plugin-sources.md
```

View file

@ -17,3 +17,9 @@ nvf-print-config | bat --language=lua
```
Alternatively, `cat` or `less` may also be used.
## Accessing `neovimConfig` {#sec-accessing-config}
It is also possible to access the configuration for the wrapped package. The
_built_ Neovim package will contain a `neovimConfig` attribute in its
`passthru`.

View file

@ -0,0 +1,131 @@
# Adding Plugins From Different Sources {#sec-plugin-sources}
**nvf** attempts to avoid depending on Nixpkgs for Neovim plugins. For the most
part, this is accomplished by defining each plugin's source and building them
from source.
[npins]: https://github.com/andir/npins
To define plugin sources, we use [npins] and pin each plugin source using
builtin fetchers. You are not bound by this restriction. In your own
configuration, any kind of fetcher or plugin source is fine.
## Nixpkgs & Friends {#ch-plugins-from-nixpkgs}
`vim.startPlugins` and `vim.optPlugins` options take either a **string**, in
which case a plugin from nvf's internal plugins registry will be used, or a
**package**. If your plugin does not require any setup, or ordering for it s
configuration, then it is possible to add it to `vim.startPlugins` to load it on
startup.
```nix
{pkgs, ...}: {
# Aerial does require some setup. In the case you pass a plugin that *does*
# require manual setup, then you must also call the setup function.
vim.startPlugins = [pkgs.vimPlugins.aerial-nvim];
}
```
[`vim.extraPlugins`]: https://notashelf.github.io/nvf/options.html#opt-vim.extraPlugins
This will fetch aerial.nvim from nixpkgs, and add it to Neovim's runtime path to
be loaded manually. Although for plugins that require manual setup, you are
encouraged to use [`vim.extraPlugins`].
```nix
{
vim.extraPlugins = {
aerial = {
package = pkgs.vimPlugins.aerial-nvim;
setup = "require('aerial').setup {}";
};
};
}
```
[custom plugins section]: https://notashelf.github.io/nvf/index.xhtml#ch-custom-plugins
More details on the extraPlugins API is documented in the
[custom plugins section].
## Building Your Own Plugins {#ch-plugins-from-source}
In the case a plugin is not available in Nixpkgs, or the Nixpkgs package is
outdated (or, more likely, broken) it is possible to build the plugins from
source using a tool, such as [npins]. You may also use your _flake inputs_ as
sources.
Example using plugin inputs:
```nix
{
# In your flake.nix
inputs = {
aerial-nvim = {
url = "github:stevearc/aerial.nvim"
flake = false;
};
};
# Make sure that 'inputs' is properly propagated into Nvf, for example, through
# specialArgs.
outputs = { ... };
}
```
In the case, you may use the input directly for the plugin's source attribute in
`buildVimPlugin`.
```nix
# Make sure that 'inputs' is properly propagated! It will be missing otherwise
# and the resulting errors might be too obscure.
{inputs, ...}: let
aerial-from-source = pkgs.vimUtils.buildVimPlugin {
name = "aerial-nvim";
src = inputs.aerial-nvim;
};
in {
vim.extraPlugins = {
aerial = {
package = aerial-from-source;
setup = "require('aerial').setup {}";
};
};
}
```
Alternatively, if you do not want to keep track of the source using flake inputs
or npins, you may call `fetchFromGitHub` (or other fetchers) directly. An
example would look like this.
```nix
regexplainer = buildVimPlugin {
name = "nvim-regexplainer";
src = fetchFromGitHub {
owner = "bennypowers";
repo = "nvim-regexplainer";
rev = "4250c8f3c1307876384e70eeedde5149249e154f";
hash = "sha256-15DLbKtOgUPq4DcF71jFYu31faDn52k3P1x47GL3+b0=";
};
# The 'buildVimPlugin' imposes some "require checks" on all plugins build from
# source. Failing tests, if they are not relevant, can be disabled using the
# 'nvimSkipModule' argument to the 'buildVimPlugin' function.
nvimSkipModule = [
"regexplainer"
"regexplainer.buffers.init"
"regexplainer.buffers.popup"
"regexplainer.buffers.register"
"regexplainer.buffers.shared"
"regexplainer.buffers.split"
"regexplainer.component.descriptions"
"regexplainer.component.init"
"regexplainer.renderers.narrative.init"
"regexplainer.renderers.narrative.narrative"
"regexplainer.renderers.init"
"regexplainer.utils.defer"
"regexplainer.utils.init"
"regexplainer.utils.treesitter"
];
}
```

View file

@ -0,0 +1,117 @@
# Pure Lua Configuration {#sec-pure-lua-config}
We recognize that you might not always want to configure your setup purely in
Nix, sometimes doing things in Lua is simply the "superior" option. In such a
case you might want to configure your Neovim instance using Lua, and nothing but
Lua. It is also possible to mix Lua and Nix configurations.
Pure Lua or hybrid Lua/Nix configurations can be achieved in two different ways.
_Purely_, by modifying Neovim's runtime directory or _impurely_ by placing Lua
configuration in a directory found in `$HOME`. For your convenience, this
section will document both methods as they can be used.
## Pure Runtime Directory {#sec-pure-nvf-runtime}
As of 0.6, nvf allows you to modify Neovim's runtime path to suit your needs.
One of the ways the new runtime option is to add a configuration **located
relative to your `flake.nix`**, which must be version controlled in pure flakes
manner.
```nix
{
# Let us assume we are in the repository root, i.e., the same directory as the
# flake.nix. For the sake of the argument, we will assume that the Neovim lua
# configuration is in a nvim/ directory relative to flake.nix.
vim = {
additionalRuntimePaths = [
# This will be added to Neovim's runtime paths. Conceptually, this behaves
# very similarly to ~/.config/nvim but you may not place a top-level
# init.lua to be able to require it directly.
./nvim
];
};
}
```
This will add the `nvim` directory, or rather, the _store path_ that will be
realised after your flake gets copied to the Nix store, to Neovim's runtime
directory. You may now create a `lua/myconfig` directory within this nvim
directory, and call it with [](#opt-vim.luaConfigRC).
```nix
{pkgs, ...}: {
vim = {
additionalRuntimePaths = [
# You can list more than one file here.
./nvim-custom-1
# To make sure list items are ordered, use lib.mkBefore or lib.mkAfter
# Simply placing list items in a given order will **not** ensure that
# this list will be deterministic.
./nvim-custom-2
];
startPlugins = [pkgs.vimPlugins.gitsigns];
# Neovim supports in-line syntax highlighting for multi-line strings.
# Simply place the filetype in a /* comment */ before the line.
luaConfigRC.myconfig = /* lua */ ''
-- Call the Lua module from ./nvim/lua/myconfig
require("myconfig")
-- Any additional Lua configuration that you might want *after* your own
-- configuration. For example, a plugin setup call.
require('gitsigns').setup({})
'';
};
}
```
## Impure Absolute Directory {#sec-impure-absolute-dir}
[Neovim 0.9]: https://github.com/neovim/neovim/pull/22128
As of [Neovim 0.9], {var}`$NVIM_APPNAME` is a variable expected by Neovim to
decide on the configuration directory. nvf sets this variable as `"nvf"`,
meaning `~/.config/nvf` will be regarded as _the_ configuration directory by
Neovim, similar to how `~/.config/nvim` behaves in regular installations. This
allows some degree of Lua configuration, backed by our low-level wrapper
[mnw](https://github.com/Gerg-L/mnw). Creating a `lua/` directory located in
`$NVIM_APPNAME` ("nvf" by default) and placing your configuration in, e.g.,
`~/.config/nvf/lua/myconfig` will allow you to `require` it as a part of the Lua
module system through nvf's module system.
Let's assume your `~/.config/nvf/lua/myconfig/init.lua` consists of the
following:
```lua
-- init.lua
vim.keymap.set("n", " ", "<Nop>", { silent = true, remap = false })
vim.g.mapleader = " "
```
The following Nix configuration via [](#opt-vim.luaConfigRC) will allow loading
this
```nix
{
# The attribute name "myconfig-dir" here is arbitrary. It is required to be
# a *named* attribute by the DAG system, but the name is entirely up to you.
vim.luaConfigRC.myconfig-dir = ''
require("myconfig")
-- Any additional Lua
'';
}
```
[DAG system]: https://notashelf.github.io/nvf/index.xhtml#ch-using-dags
After you load your custom configuration, you may use an `init.lua` located in
your custom configuration directory to configure Neovim exactly as you would
without a wrapper like nvf. If you want to place your `require` call in a
specific position (i.e., before or after options you set in nvf) the
[DAG system] will let you place your configuration in a location of your
choosing.
[top-level DAG system]: https://notashelf.github.io/nvf/index.xhtml#ch-vim-luaconfigrc

View file

@ -5,19 +5,20 @@ installing it to your machine. Below are the commands you may run to try out
different configurations provided by this flake. As of v0.5, two specialized
configurations are provided:
- **Nix** - Nix language server + simple utility plugins
- **Maximal** - Variable language servers + utility and decorative plugins
- **Nix** (`packages.nix`) - Nix language server + simple utility plugins
- **Maximal** (`packages.maximal`) - Variable language servers + utility and
decorative plugins
You may try out any of the provided configurations using the `nix run` command
on a system where Nix is installed.
```bash
```sh
$ cachix use nvf # Optional: it'll save you CPU resources and time
$ nix run github:notashelf/nvf#nix # will run the default minimal configuration
$ nix run github:notashelf/nvf#nix # Will run the default minimal configuration
```
Do keep in mind that this is **susceptible to garbage collection** meaning it
will be removed from your Nix store once you garbage collect.
Do keep in mind that this is **susceptible to garbage collection** meaning that
the built outputs will be removed from your Nix store once you garbage collect.
## Using Prebuilt Configs {#sec-using-prebuilt-configs}
@ -26,7 +27,12 @@ $ nix run github:notashelf/nvf#nix
$ nix run github:notashelf/nvf#maximal
```
### Available Configs {#sec-available-configs}
### Available Configurations {#sec-available-configs}
::: {.info}
The below configurations are provided for demonstration purposes, and are
**not** designed to be installed as is. You may
#### Nix {#sec-configs-nix}
@ -34,15 +40,33 @@ $ nix run github:notashelf/nvf#maximal
a set of visual and functional plugins. By running `nix run .#`, which is the
default package, you will build Neovim with this config.
```bash
$ nix run github:notashelf/nvf#nix test.nix
```
This command will start Neovim with some opinionated plugin configurations, and
is designed specifically for Nix. the `nix` configuration lets you see how a
fully configured Neovim setup _might_ look like without downloading too many
packages or shell utilities.
#### Maximal {#sec-configs-maximal}
`Maximal` is the ultimate configuration that will enable support for more
commonly used language as well as additional complementary plugins. Keep in
mind, however, that this will pull a lot of dependencies.
::: {.tip}
```bash
$ nix run github:notashelf/nvf#maximal -- test.nix
```
You are _strongly_ recommended to use the binary cache if you would like to try
the Maximal configuration.
It uses the same configuration template with the [Nix](#sec-configs-nix)
configuration, but supports many more languages, and enables more utility,
companion or fun plugins.
::: {.warning}
Running the maximal config will download _a lot_ of packages as it is
downloading language servers, formatters, and more. If CPU time and bandwidth
are concerns, please use the default package instead.
:::

View file

@ -50,9 +50,8 @@ soon.
- A new section has been added for language support: `vim.languages.<language>`.
- The options [](#opt-vim.languages.enableLSP),
[](#opt-vim.languages.enableTreesitter), etc. will enable the respective
section for all languages that have been enabled.
- The options `enableLSP` [](#opt-vim.languages.enableTreesitter), etc. will
enable the respective section for all languages that have been enabled.
- All LSP languages have been moved here
- `plantuml` and `markdown` have been moved here
- A new section has been added for `html`. The old

View file

@ -91,7 +91,7 @@ Release notes for release 0.5
- Updated indent-blankine.nvim to v3 - this comes with a few option changes,
which will be migrated with `renamedOptionModule`
[jacekpoz](https://jacekpoz.pl):
[poz](https://poz.pet):
- Fixed scrollOffset not being used

View file

@ -69,7 +69,7 @@ vim.api.nvim_set_keymap('n', '<leader>a', ':lua camelToSnake()<CR>', { noremap =
- Added rose-pine theme.
[jacekpoz](https://jacekpoz.pl):
[poz](https://poz.pet):
- Added `vim.autocomplete.alwaysComplete`. Allows users to have the autocomplete
window popup only when manually activated.

View file

@ -162,7 +162,7 @@ The changes are, in no particular order:
- Add [lz.n] support and lazy-load some builtin plugins.
- Add simpler helper functions for making keymaps
[jacekpoz](https://jacekpoz.pl):
[poz](https://poz.pet):
[ocaml-lsp]: https://github.com/ocaml/ocaml-lsp
[new-file-template.nvim]: https://github.com/otavioschwanck/new-file-template.nvim

View file

@ -1,9 +1,44 @@
# Release 0.8 {#sec-release-0.8}
## Breaking changes
[Lspsaga documentation]: https://nvimdev.github.io/lspsaga/
- `git-conflict` keybinds are now prefixed with `<leader>` to avoid conflicting
with builtins.
- `alpha` is now configured with nix, default config removed.
- Lspsaga module no longer ships default keybindings. The keybind format has
been changed by upstream, and old keybindings do not have equivalents under
the new API they provide. Please manually set your keybinds according to
[Lspsaga documentation] following the new API.
- none-ls has been updated to the latest version. If you have been using raw Lua
configuration to _manually_ configure it, some of the formats may become
unavailable as they have been refactored out of the main none-ls repository
upstream.
- `vim.useSystemClipboard` has been deprecated as a part of removing most
top-level convenience options, and should instead be configured in the new
module interface. You may set [](#opt-vim.clipboard.registers) appropriately
to configure Neovim to use the system clipboard.
- Changed which-key group used for gitsigns from `<leader>g` to `<leader>h` to
align with the "hunks" themed mapping and avoid conflict with the new [neogit]
group.
[NotAShelf](https://github.com/notashelf):
[typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim
[render-markdown.nvim]: https://github.com/MeanderingProgrammer/render-markdown.nvim
[yanky.nvim]: https://github.com/gbprod/yanky.nvim
[yazi.nvim]: https://github.com/mikavilpas/yazi.nvim
[snacks.nvim]: https://github.com/folke/snacks.nvim
[colorful-menu.nvim]: https://github.com/xzbdmw/colorful-menu.nvim
[oil.nvim]: https://github.com/stevearc/oil.nvim
[hunk.nvim]: https://github.com/julienvincent/hunk.nvim
[undotree]: https://github.com/mbbill/undotree
- Add [typst-preview.nvim] under
`languages.typst.extensions.typst-preview-nvim`.
@ -11,7 +46,7 @@
- Add a search widget to the options page in the nvf manual.
- Add [render-markdown.nvim] under
`languages.markdown.extensions.render-markdown-nvim`
`languages.markdown.extensions.render-markdown-nvim`.
- Implement [](#opt-vim.git.gitsigns.setupOpts) for user-specified setup table
in gitsigns configuration.
@ -33,16 +68,69 @@
- Add [](#opt-vim.lsp.lightbulb.autocmd.enable) for manually managing the
previously managed lightbulb autocommand.
- A warning will occur if [](#opt-vim.lsp.lightbulb.autocmd.enable) and
`vim.lsp.lightbulb.setupOpts.autocmd.enabled` are both set at the same time.
Pick only one.
- Add [yanky.nvim] to available plugins, under `vim.utility.yanky-nvim`.
- Fix plugin `setupOpts` for yanky.nvim and assert if shada is configured as a
backend while shada is disabled in Neovim options.
- Add [yazi.nvim] as a companion plugin for Yazi, the terminal file manager.
- Add [](#opt-vim.autocmds) and [](#opt-vim.augroups) to allow declaring
autocommands via Nix.
- Fix plugin `setupOpts` for yanky.nvim and assert if shada is configured as a
backend while shada is disabled in Neovim options.
- Add [yazi.nvim] as a companion plugin for Yazi, the terminal file manager.
- Add [snacks.nvim] under `vim.utility.snacks-nvim` as a general-purpose utility
plugin.
- Move LSPSaga to `setupOpts` format, allowing freeform configuration in
`vim.lsp.lspsaga.setupOpts`.
- Lazyload Lspsaga and remove default keybindings for it.
- Add [colorful-menu.nvim] to enhance the completion menus, with optional
integration for blink-cmp and nvim-cmp
- Add [oil.nvim] as an alternative file explorer. It will be available under
`vim.utility.oil-nvim`.
- Add `vim.diagnostics` to interact with Neovim's diagnostics module. Available
options for `vim.diagnostic.config()` can now be customized through the
[](#opt-vim.diagnostics.config) in nvf.
- Add `vim.clipboard` module for easily managing Neovim clipboard providers and
relevant packages in a simple UI.
- This deprecates `vim.useSystemClipboard` as well, see breaking changes
section above for migration options.
- Add [hunk.nvim], Neovim plugin & tool for splitting diffs in Neovim. Available
as `vim.git.hunk-nvim`
[amadaluzia](https://github.com/amadaluzia):
[haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim
- Add Haskell support under `vim.languages.haskell` using [haskell-tools.nvim].
[horriblename](https://github.com/horriblename):
[blink.cmp]: https://github.com/saghen/blink.cmp
- Add [aerial.nvim].
- Add [nvim-ufo].
- Add [blink.cmp] support.
- Add `LazyFile` user event.
- Migrate language modules from none-ls to conform/nvim-lint
- Add tsx support in conform and lint
- Moved code setting `additionalRuntimePaths` and `enableLuaLoader` out of
`luaConfigPre`'s default to prevent being overridden
- Use conform over custom autocmds for LSP format on save
[diniamo](https://github.com/diniamo):
- Add Odin support under `vim.languages.odin`.
@ -50,14 +138,6 @@
- Disable the built-in format-on-save feature of zls. Use `vim.lsp.formatOnSave`
instead.
[horriblename](https://github.com/horriblename):
[aerial.nvim]: (https://github.com/stevearc/aerial.nvim)
[nvim-ufo]: (https://github.com/kevinhwang91/nvim-ufo)
- Add [aerial.nvim]
- Add [nvim-ufo]
[LilleAila](https://github.com/LilleAila):
- Remove `vim.notes.obsidian.setupOpts.dir`, which was set by default. Fixes
@ -128,16 +208,294 @@
[thamenato](https://github.com/thamenato):
[ruff]: (https://github.com/astral-sh/ruff)
[cue]: (https://cuelang.org/)
- Add [ruff] as a formatter option in `vim.languages.python.format.type`.
- Add [cue] support under `vim.languages.cue`.
[ARCIII](https://github.com/ArmandoCIII):
[leetcode.nvim]: https://github.com/kawre/leetcode.nvim
[codecompanion-nvim]: https://github.com/olimorris/codecompanion.nvim
- Add `vim.languages.zig.dap` support through pkgs.lldb dap adapter. Code
Inspiration from `vim.languages.clang.dap` implementation.
- Add [leetcode.nvim] plugin under `vim.utility.leetcode-nvim`.
- Add [codecompanion.nvim] plugin under `vim.assistant.codecompanion-nvim`.
- Fix [codecompanion-nvim] plugin: nvim-cmp error and setupOpts defaults.
PartyWumpus:
[nezia1](https://github.com/nezia1):
[typst-concealer]: https://github.com/PartyWumpus/typst-concealer
- Add support for [nixd](https://github.com/nix-community/nixd) language server.
- Add inline typst concealing support under `vim.languages.typst` using [typst-concealer].
[jahanson](https://github.com/jahanson):
- Add [multicursors.nvim](https://github.com/smoka7/multicursors.nvim) to
available plugins, under `vim.utility.multicursors`.
- Add [hydra.nvim](https://github.com/nvimtools/hydra.nvim) as dependency for
`multicursors.nvim` and lazy loads by default.
[folospior](https://github.com/folospior):
- Fix plugin name for lsp/lspkind.
- Move `vim-illuminate` to `setupOpts format`
[iynaix](https://github.com/iynaix):
- Add lsp options support for [nixd](https://github.com/nix-community/nixd)
language server.
[Mr-Helpful](https://github.com/Mr-Helpful):
- Corrects pin names used for nvim themes.
[Libadoxon](https://github.com/Libadoxon):
- Add [git-conflict](https://github.com/akinsho/git-conflict.nvim) plugin for
resolving git conflicts.
- Add formatters for go: [gofmt](https://go.dev/blog/gofmt),
[golines](https://github.com/segmentio/golines) and
[gofumpt](https://github.com/mvdan/gofumpt).
[UltraGhostie](https://github.com/UltraGhostie)
- Add [harpoon](https://github.com/ThePrimeagen/harpoon) plugin for navigation
[MaxMur](https://github.com/TheMaxMur):
- Add YAML support under `vim.languages.yaml`.
[alfarel](https://github.com/alfarelcynthesis):
[conform.nvim]: https://github.com/stevearc/conform.nvim
- Add missing `yazi.nvim` dependency (`snacks.nvim`).
- Add [mkdir.nvim](https://github.com/jghauser/mkdir.nvim) plugin for automatic
creation of parent directories when editing a nested file.
- Add [nix-develop.nvim](https://github.com/figsoda/nix-develop.nvim) plugin for
in-neovim `nix develop`, `nix shell` and more.
- Add [direnv.vim](https://github.com/direnv/direnv.vim) plugin for automatic
syncing of nvim shell environment with direnv's.
- Add [blink.cmp] source options and some default-disabled sources.
- Add [blink.cmp] option to add
[friendly-snippets](https://github.com/rafamadriz/friendly-snippets) so
blink.cmp can source snippets from it.
- Fix [blink.cmp] breaking when built-in sources were modified.
- Fix [conform.nvim] not allowing disabling formatting on and after save. Use
`null` value to disable them if conform is enabled.
[TheColorman](https://github.com/TheColorman):
- Fix plugin `setupOpts` for `neovim-session-manager` having an invalid value
for `autoload_mode`.
[esdevries](https://github.com/esdevries):
[projekt0n/github-nvim-theme]: https://github.com/projekt0n/github-nvim-theme
- Add `github-nvim-theme` theme from [projekt0n/github-nvim-theme].
[BANanaD3V](https://github.com/BANanaD3V):
- `alpha` is now configured with nix.
- Add `markview-nvim` markdown renderer.
[viicslen](https://github.com/viicslen):
- Add `intelephense` language server support under
`vim.languages.php.lsp.server`
[Butzist](https://github.com/butzist):
- Add Helm chart support under `vim.languages.helm`.
[rice-cracker-dev](https://github.com/rice-cracker-dev):
- `eslint_d` now checks for configuration files to load.
- Fix an error where `eslint_d` fails to load.
- Add required files support for linters under
`vim.diagnostics.nvim-lint.linters.*.required_files`.
- Add global function `nvf_lint` under
`vim.diagnostics.nvim-lint.lint_function`.
- Deprecate `vim.scrollOffset` in favor of `vim.options.scrolloff`.
[Sc3l3t0n](https://github.com/Sc3l3t0n):
- Add F# support under `vim.languages.fsharp`.
[venkyr77](https://github.com/venkyr77):
- Add lint (luacheck) and formatting (stylua) support for Lua.
- Add lint (markdownlint-cli2) support for Markdown.
- Add catppuccin integration for Bufferline, Lspsaga.
- Add `neo-tree`, `snacks.explorer` integrations to `bufferline`.
- Add more applicable filetypes to illuminate denylist.
- Disable mini.indentscope for applicable filetypes.
- Fix fzf-lua having a hard dependency on fzf.
- Enable inlay hints support - `config.vim.lsp.inlayHints`.
- Add `neo-tree`, `snacks.picker` extensions to `lualine`.
- Add support for `vim.lsp.formatOnSave` and
`vim.lsp.mappings.toggleFormatOnSave`
[tebuevd](https://github.com/tebuevd):
- Fix `pickers` configuration for `telescope` by nesting it under `setupOpts`
- Fix `find_command` configuration for `telescope` by nesting it under
`setupOpts.pickers.find_files`
- Update default `telescope.setupOpts.pickers.find_files.find_command` to only
include files (and therefore exclude directories from results)
[ckoehler](https://github.com/ckoehler):
[flash.nvim]: https://github.com/folke/flash.nvim
[gitlinker.nvim]: https://github.com/linrongbin16/gitlinker.nvim
[nvim-treesitter-textobjects]: https://github.com/nvim-treesitter/nvim-treesitter-textobjects
- Fix oil config referencing snacks
- Add [flash.nvim] plugin to `vim.utility.motion.flash-nvim`
- Fix default telescope ignore list entry for '.git/' to properly match
- Add [gitlinker.nvim] plugin to `vim.git.gitlinker-nvim`
- Add [nvim-treesitter-textobjects] plugin to `vim.treesitter.textobjects`
- Default to disabling Conform for Rust if rust-analyzer is used
- To force using Conform, set `languages.rust.format.enable = true`.
[rrvsh](https://github.com/rrvsh):
- Add custom snippet support to `vim.snippets.luasnip`
- Fix namespace of python-lsp-server by changing it to python3Packages
[Noah765](https://github.com/Noah765):
[vim-sleuth]: https://github.com/tpope/vim-sleuth
- Add missing `flutter-tools.nvim` dependency `plenary.nvim`.
- Add necessary dependency of `flutter-tools.nvim` on lsp.
- Add the `vim.languages.dart.flutter-tools.flutterPackage` option.
- Fix the type of the `highlight` color options.
- Add [vim-sleuth] plugin under `vim.utility.sleuth`.
[howird](https://github.com/howird):
- Change python dap adapter name from `python` to commonly expected `debugpy`.
[aionoid](https://github.com/aionoid):
[avante-nvim]: https://github.com/yetone/avante.nvim
- Fix [render-markdown.nvim] file_types option type to list, to accept merging.
- Add [avante.nvim] plugin under `vim.assistant.avante-nvim`.
[poz](https://poz.pet):
[everforest]: https://github.com/sainnhe/everforest
- Fix gitsigns null-ls issue.
- Add [everforest] theme support.
[Haskex](https://github.com/haskex):
[Hardtime.nvim]: https://github.com/m4xshen/hardtime.nvim
- Add Plugin [Hardtime.nvim] under `vim.binds.hardtime-nvim` with `enable` and
`setupOpts` options
[taylrfnt](https://github.com/taylrfnt):
[nvim-tree](https://github.com/nvim-tree/nvim-tree.lua):
- Add missing `right_align` option for existing `renderer.icons` options.
- Add missing `render.icons` options (`hidden_placement`,
`diagnostics_placement`, and `bookmarks_placement`).
[cramt](https://github.com/cramt):
- Add `rubylsp` option in `vim.languages.ruby.lsp.server` to use shopify's
ruby-lsp language server
[Haskex](https://github.com/haskex):
[solarized-osaka.nvim]: https://github.com/craftzdog/solarized-osaka.nvim
- Add [solarized-osaka.nvim] theme
[img-clip.nvim]: https://github.com/hakonharnes/img-clip.nvim
- Add [img-clip.nvim] plugin in `vim.utility.images.img-clip` with `enable` and
`setupOpts`
- Add `vim.utility.images.img-clip.enable = isMaximal` in configuration.nix
[anil9](https://github.com/anil9):
[clojure-lsp]: https://github.com/clojure-lsp/clojure-lsp
[conjure]: https://github.com/Olical/conjure
- Add Clojure support under `vim.languages.clojure` using [clojure-lsp]
- Add code evaluation environment [conjure] under `vim.repl.conjure`
[CallumGilly](https://github.com/CallumGilly):
- Add missing `transparent` option for existing
[onedark.nvim](https://github.com/navarasu/onedark.nvim) theme.
[theutz](https://github.com/theutz):
- Added "auto" flavour for catppuccin theme
[lackac](https://github.com/lackac):
[solarized.nvim]: https://github.com/maxmx03/solarized.nvim
[smart-splits.nvim]: https://github.com/mrjones2014/smart-splits.nvim
[neogit]: https://github.com/NeogitOrg/neogit
- Add [solarized.nvim] theme with support for multiple variants
- Add [smart-splits.nvim] for navigating between Neovim windows and terminal
multiplexer panes. Available at `vim.utility.smart-splits`.
- Restore vim-dirtytalk plugin and fix ordering with spellcheck in generated
config.
- Fix lualine separator options
- Add [neogit], an interactive and powerful Git interface for Neovim, inspired
by Magit
- Allow deregistering which-key binds or groups by setting them to `null`
[justDeeevin](https://github.com/justDeeevin):
[supermaven-nvim]: https://github.com/supermaven-inc/supermaven-nvim
- Add [supermaven-nvim] plugin in `vim.assistant.supermaven-nvim` with `enable`
and `setupOpts`
[trueNAHO](https://github.com/trueNAHO):
- `flake-parts`'s `nixpkgs-lib` input follows nvf's `nixpkgs` input to reduce
download size.
- `flake-utils`'s `systems` inputs follows nvf's `systems` input to transitively
leverage the pattern introduced in commit
[fc8206e7a61d ("flake: utilize
nix-systems for overridable flake systems")](https://github.com/NotAShelf/nvf/commit/fc8206e7a61d7eb02006f9010e62ebdb3336d0d2).
[soliprem](https://github.com/soliprem):
- fix broken `neorg` grammars
- remove obsolete warning in the `otter` module
[Cool-Game-Dev](https://github.com/Cool-Game-Dev):
[nvim-biscuits]: https://github.com/code-biscuits/nvim-biscuits
- Add [nvim-biscuits] to show block context. Available at
`vim.utility.nvim-biscuits`.
[JManch](https://github.com/JManch):
- Fix default [blink.cmp] sources "path" and "buffer" not working when
`autocomplete.nvim-cmp.enable` was disabled and
`autocomplete.nvim-cmp.sources` had not been modified.
[Jules](https://github.com/jules-sommer):
[nvim-highlight-colors]: https://github.com/brenoprata10/nvim-highlight-colors
- Add [nvim-highlight-colors] plugin in `vim.ui.nvim-highlight-colors` with
`enable` and `setupOpts`

2974
flake.lock generated

File diff suppressed because it is too large Load diff

946
flake.nix
View file

@ -5,9 +5,10 @@
self,
...
} @ inputs: let
# call the extended library with `inputs`
# inputs is used to get the original standard library, and to pass inputs to the plugin autodiscovery function
lib = import ./lib/stdlib-extended.nix inputs;
# Call the extended library with `inputs`.
# inputs is used to get the original standard library, and to pass inputs
# to the plugin autodiscovery function
lib = import ./lib/stdlib-extended.nix {inherit inputs self;};
in
flake-parts.lib.mkFlake {
inherit inputs;
@ -17,9 +18,8 @@
# «https://github.com/nix-systems/nix-systems»
systems = import inputs.systems;
imports = [
./flake/templates
./flake/apps.nix
./flake/legacyPackages.nix
./flake/overlays.nix
./flake/packages.nix
./flake/develop.nix
];
@ -30,8 +30,10 @@
inherit (lib.nvim) neovimConfiguration;
};
inherit (lib.importJSON ./npins/sources.json) pins;
homeManagerModules = {
nvf = import ./flake/modules/home-manager.nix {inherit lib self;};
nvf = import ./flake/modules/home-manager.nix {inherit lib inputs;};
default = self.homeManagerModules.nvf;
neovim-flake =
lib.warn ''
@ -42,7 +44,7 @@
};
nixosModules = {
nvf = import ./flake/modules/nixos.nix {inherit lib self;};
nvf = import ./flake/modules/nixos.nix {inherit lib inputs;};
default = self.nixosModules.nvf;
neovim-flake =
lib.warn ''
@ -54,16 +56,30 @@
};
perSystem = {pkgs, ...}: {
# Provide the default formatter. `nix fmt` in project root
# will format available files with the correct formatter.
# P.S: Please do not format with nixfmt! It messes with many
# syntax elements and results in unreadable code.
formatter = pkgs.alejandra;
# Provides the default formatter for 'nix fmt', which will format the
# entire tree with Alejandra. The wrapper script is necessary due to
# changes to the behaviour of Nix, which now encourages wrappers for
# tree-wide formatting.
formatter = pkgs.writeShellApplication {
name = "nix3-fmt-wrapper";
# Check if codebase is properly formatted.
# This can be initiated with `nix build .#checks.<system>.nix-fmt`
# or with `nix flake check`
runtimeInputs = [
pkgs.alejandra
pkgs.fd
];
text = ''
# Find Nix files in the tree and format them with Alejandra
fd "$@" -t f -e nix -x alejandra -q '{}'
'';
};
# Provides checks to be built an ran on 'nix flake check'. They can also
# be built individually with 'nix build' as described below.
checks = {
# Check if codebase is properly formatted.
# This can be initiated with `nix build .#checks.<system>.nix-fmt`
# or with `nix flake check`
nix-fmt = pkgs.runCommand "nix-fmt-check" {nativeBuildInputs = [pkgs.alejandra];} ''
alejandra --check ${self} < /dev/null | tee $out
'';
@ -71,899 +87,23 @@
};
};
# Flake inputs
inputs = {
systems.url = "github:nix-systems/default";
## Basic Inputs
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
flake-utils.url = "github:numtide/flake-utils";
systems.url = "github:nix-systems/default";
flake-parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
flake-compat = {
url = "git+https://git.lix.systems/lix-project/flake-compat.git";
flake = false;
};
# Alternate neovim-wrapper
mnw.url = "github:Gerg-L/mnw";
# For generating documentation website
nmd = {
url = "sourcehut:~rycee/nmd";
flake = false;
};
# Language servers (use master instead of nixpkgs)
nil = {
url = "github:oxalica/nil";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-utils.follows = "flake-utils";
};
## Plugins
# Lazy loading
plugin-lz-n = {
url = "github:nvim-neorocks/lz.n";
flake = false;
};
plugin-lzn-auto-require = {
url = "github:horriblename/lzn-auto-require/require-rewrite";
flake = false;
};
plugin-rtp-nvim = {
url = "github:nvim-neorocks/rtp.nvim";
flake = false;
};
# LSP plugins
plugin-nvim-lspconfig = {
url = "github:neovim/nvim-lspconfig";
flake = false;
};
plugin-lspsaga = {
url = "github:tami5/lspsaga.nvim";
flake = false;
};
plugin-lspkind = {
url = "github:onsails/lspkind-nvim";
flake = false;
};
plugin-trouble = {
url = "github:folke/trouble.nvim";
flake = false;
};
plugin-nvim-treesitter-context = {
url = "github:nvim-treesitter/nvim-treesitter-context";
flake = false;
};
plugin-nvim-lightbulb = {
url = "github:kosayoda/nvim-lightbulb";
flake = false;
};
plugin-fastaction-nvim = {
url = "github:Chaitanyabsprip/fastaction.nvim";
flake = false;
};
plugin-lsp-signature = {
url = "github:ray-x/lsp_signature.nvim";
flake = false;
};
plugin-lsp-lines = {
url = "sourcehut:~whynothugo/lsp_lines.nvim";
flake = false;
};
plugin-none-ls = {
# https://github.com/nvimtools/none-ls.nvim/issues/58
url = "github:nvimtools/none-ls.nvim/bb680d752cec37949faca7a1f509e2fe67ab418a";
flake = false;
};
plugin-nvim-docs-view = {
url = "github:amrbashir/nvim-docs-view";
flake = false;
};
plugin-otter-nvim = {
url = "github:jmbuhr/otter.nvim";
flake = false;
};
# Language support
plugin-sqls-nvim = {
url = "github:nanotee/sqls.nvim";
flake = false;
};
plugin-rustaceanvim = {
url = "github:mrcjkb/rustaceanvim";
flake = false;
};
plugin-flutter-tools = {
url = "github:akinsho/flutter-tools.nvim";
flake = false;
};
plugin-neodev-nvim = {
url = "github:folke/neodev.nvim";
flake = false;
};
plugin-elixir-tools = {
url = "github:elixir-tools/elixir-tools.nvim";
flake = false;
};
plugin-ts-error-translator = {
url = "github:dmmulroy/ts-error-translator.nvim";
flake = false;
};
plugin-typst-preview-nvim = {
url = "github:chomosuke/typst-preview.nvim";
flake = false;
};
plugin-typst-concealer = {
url = "github:PartyWumpus/typst-concealer";
flake = false;
};
plugin-nvim-metals = {
url = "github:scalameta/nvim-metals";
flake = false;
};
plugin-omnisharp-extended = {
url = "github:Hoffs/omnisharp-extended-lsp.nvim";
flake = false;
};
plugin-csharpls-extended = {
url = "github:Decodetalkers/csharpls-extended-lsp.nvim";
flake = false;
};
# Copying/Registers
plugin-registers = {
url = "github:tversteeg/registers.nvim";
flake = false;
};
plugin-nvim-neoclip = {
url = "github:AckslD/nvim-neoclip.lua";
flake = false;
};
# Pickers
plugin-telescope = {
url = "github:nvim-telescope/telescope.nvim";
flake = false;
};
plugin-fzf-lua = {
url = "github:ibhagwan/fzf-lua";
flake = false;
};
# Runners
plugin-run-nvim = {
url = "github:diniamo/run.nvim";
flake = false;
};
# Debuggers
plugin-nvim-dap = {
url = "github:mfussenegger/nvim-dap";
flake = false;
};
plugin-nvim-dap-ui = {
url = "github:rcarriga/nvim-dap-ui";
flake = false;
};
plugin-nvim-dap-go = {
url = "github:leoluz/nvim-dap-go";
flake = false;
};
# Filetrees
plugin-nvim-tree-lua = {
url = "github:nvim-tree/nvim-tree.lua";
flake = false;
};
plugin-neo-tree-nvim = {
url = "github:nvim-neo-tree/neo-tree.nvim";
flake = false;
};
# Tablines
plugin-nvim-bufferline-lua = {
url = "github:akinsho/nvim-bufferline.lua";
flake = false;
};
# Statuslines
plugin-lualine = {
url = "github:hoob3rt/lualine.nvim";
flake = false;
};
plugin-nvim-cmp = {
url = "github:hrsh7th/nvim-cmp";
flake = false;
};
plugin-cmp-buffer = {
url = "github:hrsh7th/cmp-buffer";
flake = false;
};
plugin-cmp-nvim-lsp = {
url = "github:hrsh7th/cmp-nvim-lsp";
flake = false;
};
plugin-cmp-path = {
url = "github:hrsh7th/cmp-path";
flake = false;
};
plugin-cmp-treesitter = {
url = "github:ray-x/cmp-treesitter";
flake = false;
};
plugin-cmp-luasnip = {
url = "github:saadparwaiz1/cmp_luasnip";
flake = false;
};
# snippets
plugin-luasnip = {
url = "github:L3MON4D3/LuaSnip";
flake = false;
};
plugin-friendly-snippets = {
url = "github:rafamadriz/friendly-snippets";
flake = false;
};
# Presence
plugin-neocord = {
url = "github:IogaMaster/neocord";
flake = false; # uses flake-utils, avoid the flake
};
# Autopairs
plugin-nvim-autopairs = {
url = "github:windwp/nvim-autopairs";
flake = false;
};
plugin-nvim-ts-autotag = {
url = "github:windwp/nvim-ts-autotag";
flake = false;
};
# Commenting
plugin-comment-nvim = {
url = "github:numToStr/Comment.nvim";
flake = false;
};
plugin-todo-comments = {
url = "github:folke/todo-comments.nvim";
flake = false;
};
# Buffer tools
plugin-bufdelete-nvim = {
url = "github:famiu/bufdelete.nvim";
flake = false;
};
# Dashboard Utilities
plugin-dashboard-nvim = {
url = "github:glepnir/dashboard-nvim";
flake = false;
};
plugin-alpha-nvim = {
url = "github:goolord/alpha-nvim";
flake = false;
};
plugin-vim-startify = {
url = "github:mhinz/vim-startify";
flake = false;
};
# Themes
plugin-base16 = {
url = "github:rrethy/base16-nvim";
flake = false;
};
plugin-tokyonight = {
url = "github:folke/tokyonight.nvim";
flake = false;
};
plugin-onedark = {
url = "github:navarasu/onedark.nvim";
flake = false;
};
plugin-catppuccin = {
url = "github:catppuccin/nvim";
flake = false;
};
plugin-dracula = {
url = "github:Mofiqul/dracula.nvim";
flake = false;
};
plugin-oxocarbon = {
url = "github:nyoom-engineering/oxocarbon.nvim";
flake = false;
};
plugin-gruvbox = {
url = "github:ellisonleao/gruvbox.nvim";
flake = false;
};
plugin-rose-pine = {
url = "github:rose-pine/neovim";
flake = false;
};
plugin-nord = {
url = "github:gbprod/nord.nvim";
flake = false;
};
# Rust crates
plugin-crates-nvim = {
url = "github:Saecki/crates.nvim";
flake = false;
};
# Project Management
plugin-project-nvim = {
url = "github:ahmedkhalf/project.nvim";
flake = false;
};
# Visuals
plugin-nvim-cursorline = {
url = "github:yamatsum/nvim-cursorline";
flake = false;
};
plugin-nvim-scrollbar = {
url = "github:petertriho/nvim-scrollbar";
flake = false;
};
plugin-cinnamon-nvim = {
url = "github:declancm/cinnamon.nvim";
flake = false;
};
plugin-cellular-automaton = {
url = "github:Eandrju/cellular-automaton.nvim";
flake = false;
};
plugin-indent-blankline = {
url = "github:lukas-reineke/indent-blankline.nvim";
flake = false;
};
plugin-nvim-web-devicons = {
url = "github:nvim-tree/nvim-web-devicons";
flake = false;
};
plugin-tiny-devicons-auto-colors = {
url = "github:rachartier/tiny-devicons-auto-colors.nvim";
flake = false;
};
plugin-gitsigns-nvim = {
url = "github:lewis6991/gitsigns.nvim";
flake = false;
};
plugin-vim-fugitive = {
url = "github:tpope/vim-fugitive";
flake = false;
};
plugin-fidget-nvim = {
url = "github:j-hui/fidget.nvim";
flake = false;
};
plugin-highlight-undo = {
url = "github:tzachar/highlight-undo.nvim";
flake = false;
};
plugin-render-markdown-nvim = {
url = "github:MeanderingProgrammer/render-markdown.nvim";
flake = false;
};
plugin-rainbow-delimiters = {
url = "github:HiPhish/rainbow-delimiters.nvim";
flake = false;
};
# Minimap
plugin-minimap-vim = {
url = "github:wfxr/minimap.vim";
flake = false;
};
plugin-codewindow-nvim = {
url = "github:gorbit99/codewindow.nvim";
flake = false;
};
# Notifications
plugin-nvim-notify = {
url = "github:rcarriga/nvim-notify";
flake = false;
};
# Utilities
plugin-ccc = {
url = "github:uga-rosa/ccc.nvim";
flake = false;
};
plugin-diffview-nvim = {
url = "github:sindrets/diffview.nvim";
flake = false;
};
plugin-icon-picker-nvim = {
url = "github:ziontee113/icon-picker.nvim";
flake = false;
};
plugin-which-key = {
url = "github:folke/which-key.nvim";
flake = false;
};
plugin-cheatsheet-nvim = {
url = "github:sudormrfbin/cheatsheet.nvim";
flake = false;
};
plugin-gesture-nvim = {
url = "github:notomo/gesture.nvim";
flake = false;
};
plugin-hop-nvim = {
url = "github:phaazon/hop.nvim";
flake = false;
};
plugin-leap-nvim = {
url = "github:ggandor/leap.nvim";
flake = false;
};
plugin-smartcolumn = {
url = "github:m4xshen/smartcolumn.nvim";
flake = false;
};
plugin-nvim-surround = {
url = "github:kylechui/nvim-surround";
flake = false;
};
plugin-glow-nvim = {
url = "github:ellisonleao/glow.nvim";
flake = false;
};
plugin-image-nvim = {
url = "github:3rd/image.nvim";
flake = false;
};
plugin-precognition-nvim = {
url = "github:tris203/precognition.nvim";
flake = false;
};
# Note-taking
plugin-obsidian-nvim = {
url = "github:epwalsh/obsidian.nvim";
flake = false;
};
plugin-orgmode-nvim = {
url = "github:nvim-orgmode/orgmode";
flake = false;
};
plugin-mind-nvim = {
url = "github:phaazon/mind.nvim";
flake = false;
};
# Spellchecking
plugin-vim-dirtytalk = {
url = "github:psliwka/vim-dirtytalk";
flake = false;
};
# Terminal
plugin-toggleterm-nvim = {
url = "github:akinsho/toggleterm.nvim";
flake = false;
};
# UI
plugin-nvim-navbuddy = {
url = "github:SmiteshP/nvim-navbuddy";
flake = false;
};
plugin-nvim-navic = {
url = "github:SmiteshP/nvim-navic";
flake = false;
};
plugin-noice-nvim = {
url = "github:folke/noice.nvim";
flake = false;
};
plugin-modes-nvim = {
url = "github:mvllow/modes.nvim";
flake = false;
};
plugin-nvim-colorizer-lua = {
url = "github:NvChad/nvim-colorizer.lua";
flake = false;
};
plugin-vim-illuminate = {
url = "github:RRethy/vim-illuminate";
flake = false;
};
# Assistant
plugin-chatgpt = {
url = "github:jackMort/ChatGPT.nvim";
flake = false;
};
plugin-copilot-lua = {
url = "github:zbirenbaum/copilot.lua";
flake = false;
};
plugin-copilot-cmp = {
url = "github:zbirenbaum/copilot-cmp";
flake = false;
};
# Session management
plugin-nvim-session-manager = {
url = "github:Shatur/neovim-session-manager";
flake = false;
};
# Dependencies
plugin-plenary-nvim = {
# (required by crates-nvim)
url = "github:nvim-lua/plenary.nvim";
flake = false;
};
plugin-dressing-nvim = {
# (required by icon-picker-nvim)
url = "github:stevearc/dressing.nvim";
flake = false;
};
plugin-vim-markdown = {
# (required by obsidian-nvim)
url = "github:preservim/vim-markdown";
flake = false;
};
plugin-tabular = {
# (required by vim-markdown)
url = "github:godlygeek/tabular";
flake = false;
};
plugin-lua-utils-nvim = {
url = "github:nvim-neorg/lua-utils.nvim";
flake = false;
};
plugin-pathlib-nvim = {
url = "github:pysan3/pathlib.nvim";
flake = false;
};
plugin-neorg = {
url = "github:nvim-neorg/neorg";
flake = false;
};
plugin-neorg-telescope = {
url = "github:nvim-neorg/neorg-telescope";
flake = false;
};
plugin-nui-nvim = {
# (required by noice.nvim)
url = "github:MunifTanjim/nui.nvim";
flake = false;
};
plugin-vim-repeat = {
# (required by leap.nvim)
url = "github:tpope/vim-repeat";
flake = false;
};
plugin-nvim-nio = {
# (required by nvim-dap-ui)
url = "github:nvim-neotest/nvim-nio";
flake = false;
};
plugin-promise-async = {
url = "github:kevinhwang91/promise-async";
flake = false;
};
plugin-nvim-ufo = {
url = "github:kevinhwang91/nvim-ufo";
flake = false;
};
plugin-new-file-template-nvim = {
# (required by new-file-template.nvim)
url = "github:otavioschwanck/new-file-template.nvim";
flake = false;
};
plugin-haskell-tools-nvim = {
url = "github:mrcjkb/haskell-tools.nvim";
flake = false;
};
plugin-aerial-nvim = {
url = "github:stevearc/aerial.nvim";
flake = false;
};
# Mini.nvim
plugin-mini-ai = {
url = "github:echasnovski/mini.ai";
flake = false;
};
plugin-mini-align = {
url = "github:echasnovski/mini.align";
flake = false;
};
plugin-mini-animate = {
url = "github:echasnovski/mini.animate";
flake = false;
};
plugin-mini-base16 = {
url = "github:echasnovski/mini.base16";
flake = false;
};
plugin-mini-basics = {
url = "github:echasnovski/mini.basics";
flake = false;
};
plugin-mini-bracketed = {
url = "github:echasnovski/mini.bracketed";
flake = false;
};
plugin-mini-bufremove = {
url = "github:echasnovski/mini.bufremove";
flake = false;
};
plugin-mini-clue = {
url = "github:echasnovski/mini.clue";
flake = false;
};
plugin-mini-colors = {
url = "github:echasnovski/mini.colors";
flake = false;
};
plugin-mini-comment = {
url = "github:echasnovski/mini.comment";
flake = false;
};
plugin-mini-completion = {
url = "github:echasnovski/mini.completion";
flake = false;
};
plugin-mini-diff = {
url = "github:echasnovski/mini.diff";
flake = false;
};
plugin-mini-doc = {
url = "github:echasnovski/mini.doc";
flake = false;
};
plugin-mini-extra = {
url = "github:echasnovski/mini.extra";
flake = false;
};
plugin-mini-files = {
url = "github:echasnovski/mini.files";
flake = false;
};
plugin-mini-fuzzy = {
url = "github:echasnovski/mini.fuzzy";
flake = false;
};
plugin-mini-git = {
url = "github:echasnovski/mini-git";
flake = false;
};
plugin-mini-hipatterns = {
url = "github:echasnovski/mini.hipatterns";
flake = false;
};
plugin-mini-hues = {
url = "github:echasnovski/mini.hues";
flake = false;
};
plugin-mini-icons = {
url = "github:echasnovski/mini.icons";
flake = false;
};
plugin-mini-indentscope = {
url = "github:echasnovski/mini.indentscope";
flake = false;
};
plugin-mini-jump = {
url = "github:echasnovski/mini.jump";
flake = false;
};
plugin-mini-jump2d = {
url = "github:echasnovski/mini.jump2d";
flake = false;
};
plugin-mini-map = {
url = "github:echasnovski/mini.map";
flake = false;
};
plugin-mini-misc = {
url = "github:echasnovski/mini.misc";
flake = false;
};
plugin-mini-move = {
url = "github:echasnovski/mini.move";
flake = false;
};
plugin-mini-notify = {
url = "github:echasnovski/mini.notify";
flake = false;
};
plugin-mini-operators = {
url = "github:echasnovski/mini.operators";
flake = false;
};
plugin-mini-pairs = {
url = "github:echasnovski/mini.pairs";
flake = false;
};
plugin-mini-pick = {
url = "github:echasnovski/mini.pick";
flake = false;
};
plugin-mini-sessions = {
url = "github:echasnovski/mini.sessions";
flake = false;
};
plugin-mini-snippets = {
url = "github:echasnovski/mini.snippets";
flake = false;
};
plugin-mini-splitjoin = {
url = "github:echasnovski/mini.splitjoin";
flake = false;
};
plugin-mini-starter = {
url = "github:echasnovski/mini.starter";
flake = false;
};
plugin-mini-statusline = {
url = "github:echasnovski/mini.statusline";
flake = false;
};
plugin-mini-surround = {
url = "github:echasnovski/mini.surround";
flake = false;
};
plugin-mini-tabline = {
url = "github:echasnovski/mini.tabline";
flake = false;
};
plugin-mini-test = {
url = "github:echasnovski/mini.test";
flake = false;
};
plugin-mini-trailspace = {
url = "github:echasnovski/mini.trailspace";
flake = false;
};
plugin-mini-visits = {
url = "github:echasnovski/mini.visits";
flake = false;
};
};
}

View file

@ -3,13 +3,14 @@
pkgs,
config,
self',
inputs',
...
}: {
devShells = {
default = self'.devShells.lsp;
nvim-nix = pkgs.mkShellNoCC {packages = [config.packages.nix];};
lsp = pkgs.mkShellNoCC {
packages = with pkgs; [nil statix deadnix alejandra];
packages = with pkgs; [nil statix deadnix alejandra npins];
};
};

View file

@ -1,20 +0,0 @@
{inputs, ...}: {
perSystem = {
system,
inputs',
...
}: {
legacyPackages = import inputs.nixpkgs {
inherit system;
overlays = [
inputs.self.overlays.default
(_: _: {
# Build nil from source to get most recent
# features as they are added.
nil = inputs'.nil.packages.default;
})
];
};
};
}

View file

@ -1,13 +1,13 @@
# Home Manager module
{
self,
inputs,
lib,
}: {
config,
pkgs,
...
}: let
inherit (self) packages inputs;
inherit (inputs.self) packages;
inherit (lib) maintainers;
inherit (lib.modules) mkIf mkAliasOptionModule;
inherit (lib.lists) optional;

View file

@ -1,13 +1,13 @@
# NixOS module
{
self,
inputs,
lib,
}: {
config,
pkgs,
...
}: let
inherit (self) inputs packages;
inherit (inputs.self) packages;
inherit (lib) maintainers;
inherit (lib.modules) mkIf mkOverride mkAliasOptionModule;
inherit (lib.lists) optional;

View file

@ -1,19 +0,0 @@
{
pkgs,
lib,
...
}: let
inherit (lib.nvim) neovimConfiguration;
buildPkg = pkgs: modules: (neovimConfiguration {inherit pkgs modules;}).neovim;
nixConfig = import ../configuration.nix false;
maximalConfig = import ../configuration.nix true;
in {
flake.overlays.default = _final: prev: {
inherit neovimConfiguration;
neovim-nix = buildPkg prev [nixConfig];
neovim-maximal = buildPkg prev [maximalConfig];
devPkg = buildPkg pkgs [nixConfig {config.vim.languages.html.enable = pkgs.lib.mkForce true;}];
};
}

View file

@ -1,71 +1,122 @@
{inputs, ...}: {
{
inputs,
self,
...
} @ args: {
perSystem = {
config,
pkgs,
lib,
...
}: let
inherit (lib.customisation) makeScope;
inherit (lib.attrsets) isDerivation isAttrs concatMapAttrs;
inherit (lib.strings) concatStringsSep;
inherit (lib.filesystem) packagesFromDirectoryRecursive;
# Entrypoint for nvf documentation and relevant packages.
docs = import ../docs {inherit pkgs inputs lib;};
# Helper function for creating demo configurations for nvf
# TODO: make this more generic.
buildPkg = maximal:
(args.config.flake.lib.nvim.neovimConfiguration {
inherit pkgs;
modules = [(import ../configuration.nix maximal)];
}).neovim;
# This constructs a by-name overlay similar to the one found in Nixpkgs.
# The goal is to automatically discover and packages found in pkgs/by-name
# as long as they have a 'package.nix' in the package directory. We also
# pass 'inputs' and 'pins' to all packages in the 'callPackage' scope, therefore
# they are always available in the relevant 'package.nix' files.
# ---
# The logic is borrowed from drupol/pkgs-by-name-for-flake-parts, available
# under the MIT license.
flattenPkgs = separator: path: value:
if isDerivation value
then {
${concatStringsSep separator path} = value;
}
else if isAttrs value
then concatMapAttrs (name: flattenPkgs separator (path ++ [name])) value
else
# Ignore the functions which makeScope returns
{};
inputsScope = makeScope pkgs.newScope (_: {
inherit inputs;
inherit (self) pins;
});
scopeFromDirectory = directory:
packagesFromDirectoryRecursive {
inherit directory;
inherit (inputsScope) newScope callPackage;
};
legacyPackages = scopeFromDirectory ./pkgs/by-name;
in {
packages = {
inherit (docs.manual) htmlOpenTool;
# Documentation
docs = docs.manual.html;
docs-html = docs.manual.html;
docs-manpages = docs.manPages;
docs-json = docs.options.json;
docs-linkcheck = let
site = config.packages.docs;
in
pkgs.testers.lycheeLinkCheck {
inherit site;
remap = {
"https://notashelf.github.io/nvf/" = site;
};
extraConfig = {
exclude = [];
include_mail = true;
include_verbatim = true;
};
};
packages =
(flattenPkgs "/" [] legacyPackages)
// {
inherit (docs.manual) htmlOpenTool;
# Build and open the built manual in your system browser
docs-html-wrapped = pkgs.writeScriptBin "docs-html-wrapped" ''
#!${pkgs.stdenv.shell}
# use xdg-open to open the docs in the browser
${pkgs.xdg-utils}/bin/xdg-open ${docs.manual.html}
'';
# Documentation
docs = docs.manual.html;
docs-html = docs.manual.html;
docs-manpages = docs.manPages;
docs-json = docs.options.json;
docs-linkcheck = let
site = config.packages.docs;
in
pkgs.testers.lycheeLinkCheck {
inherit site;
# Exposed neovim configurations
nix = config.legacyPackages.neovim-nix;
maximal = config.legacyPackages.neovim-maximal;
default = config.legacyPackages.neovim-nix;
remap = {
"https://notashelf.github.io/nvf/" = site;
};
# Published docker images
docker-nix = let
inherit (pkgs) bash gitFull buildEnv;
inherit (config.legacyPackages) neovim-nix;
in
pkgs.dockerTools.buildImage {
name = "nvf";
tag = "latest";
copyToRoot = buildEnv {
name = "neovim-root";
pathsToLink = ["/bin"];
paths = [
neovim-nix
gitFull
bash
];
extraConfig = {
exclude = [];
include_mail = true;
include_verbatim = true;
};
};
config = {
Cmd = ["${neovim-nix}/bin/nvim"];
WorkingDir = "/home/neovim/demo";
Volumes = {"/home/neovim/demo" = {};};
};
};
};
# Helper utility for building the HTML manual and opening it in the
# browser with $BROWSER or using xdg-open as a fallback tool.
# Adapted from Home-Manager, available under the MIT license.
docs-html-wrapped = let
xdg-open = lib.getExe' pkgs.xdg-utils "xdg-open";
docs-html = docs.manual.html + /share/doc/nvf;
in
pkgs.writeShellScriptBin "docs-html-wrapped" ''
set -euo pipefail
if [[ ! -v BROWSER || -z $BROWSER ]]; then
for candidate in xdg-open open w3m; do
BROWSER="$(type -P $candidate || true)"
if [[ -x $BROWSER ]]; then
break;
fi
done
fi
if [[ ! -v BROWSER || -z $BROWSER ]]; then
echo "$0: unable to start a web browser; please set \$BROWSER"
echo "$0: Trying xdg-open as a fallback"
${xdg-open} ${docs-html}/index.xhtml
else
echo "\$BROWSER is set. Attempting to open manual"
exec "$BROWSER" "${docs-html}/index.xhtml"
fi
'';
# Exposed neovim configurations
nix = buildPkg false;
maximal = buildPkg true;
default = config.packages.nix;
};
};
}

View file

@ -0,0 +1,70 @@
{
pins,
openssl,
pkg-config,
rustPlatform,
stdenv,
vimUtils,
makeWrapper,
pkgs,
...
}: let
# From npins
pin = pins.avante-nvim;
version = pin.branch;
src = pkgs.fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = pin.revision;
sha256 = pin.hash;
};
avante-nvim-lib = rustPlatform.buildRustPackage {
pname = "avante-nvim-lib";
inherit version src;
cargoHash = "sha256-pTWCT2s820mjnfTscFnoSKC37RE7DAPKxP71QuM+JXQ=";
nativeBuildInputs = [
pkg-config
makeWrapper
pkgs.perl
];
buildInputs = [
openssl
];
buildFeatures = ["luajit"];
checkFlags = [
# Disabled because they access the network.
"--skip=test_hf"
"--skip=test_public_url"
"--skip=test_roundtrip"
"--skip=test_fetch_md"
];
};
in
vimUtils.buildVimPlugin {
pname = "avante-nvim";
inherit version src;
doCheck = false;
postInstall = let
ext = stdenv.hostPlatform.extensions.sharedLibrary;
in ''
mkdir -p $out/build
for lib in "avante_repo_map" "avante_templates" "avante_tokenizers" "avante_html2md"; do
ln -s ${avante-nvim-lib}/lib/lib$lib${ext} $out/build/$lib${ext}
done
'';
nvimSkipModules = [
# Requires setup with corresponding provider
"avante.providers.azure"
"avante.providers.copilot"
"avante.providers.vertex_claude"
"avante.providers.ollama"
];
}

View file

@ -0,0 +1,39 @@
{
rustPlatform,
fetchFromGitHub,
writeShellScriptBin,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "blink-cmp";
version = "1.6.0";
src = fetchFromGitHub {
owner = "Saghen";
repo = "blink.cmp";
tag = "v${finalAttrs.version}";
hash = "sha256-IHRYgKcYP+JDGu8Vtawgzlhq25vpROFqb8KmpfVMwCk=";
};
forceShare = [
"man"
"info"
];
postInstall = ''
cp -r {lua,plugin} "$out"
mkdir -p "$out/doc"
cp 'doc/'*'.txt' "$out/doc/"
mkdir -p "$out/target"
mv "$out/lib" "$out/target/release"
'';
cargoHash = "sha256-QsVCugYWRri4qu64wHnbJQZBhy4tQrr+gCYbXtRBlqE=";
nativeBuildInputs = [
(writeShellScriptBin "git" "exit 1")
];
env.RUSTC_BOOTSTRAP = true;
})

View file

@ -0,0 +1,17 @@
{
flake.templates = {
standalone = {
path = ./standalone;
description = "Standalone flake template for nvf";
welcomeText = ''
Template flake.nix has been created in flake.nix!
Note that this is a very basic example to bootstrap nvf for you. Please edit your
configuration as described in the nvf manual before using this template. The
configured packages will be ran with 'nix run .' or 'nix run .#neovimConfigured'
Happy editing!
'';
};
};
}

View file

@ -0,0 +1,74 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nvf.url = "github:notashelf/nvf";
};
outputs = {
self,
nixpkgs,
...
} @ inputs: let
# An abstraction over systems to easily provide the same package
# for multiple systems. This is preferable to abstraction libraries.
forEachSystem = nixpkgs.lib.genAttrs ["x86_64-linux"];
in {
packages = forEachSystem (system: let
pkgs = inputs.nixpkgs.legacyPackages.${system};
# A module to be evaluated via lib.evalModules inside nvf's module system.
# All options supported by nvf will go under config.vim to create the final
# wrapped package. You may also add some new *options* under options.* to
# expand the module system.
configModule = {
# You may browse available options for nvf on the online manual. Please see
# <https://notashelf.github.io/nvf/options.html>
config.vim = {
theme.enable = true;
lsp = {
# Enable LSP functionality globally. This is required for modules found
# in `vim.languages` to enable relevant LSPs.
enable = true;
# You may define your own LSP configurations using `vim.lsp.servers` in
# nvf without ever needing lspconfig to do it. This will use the native
# API provided by Neovim > 0.11
servers = {};
};
# Language support and automatic configuration of companion plugins.
# Note that enabling, e.g., languages.<lang>.diagnostics will automatically
# enable top-level options such as enableLSP or enableExtraDiagnostics as
# they are needed.
languages = {
enableFormat = true;
enableTreesitter = true;
enableExtraDiagnostics = true;
# Nix language and diagnostics.
nix.enable = true;
};
};
};
# Evaluate any and all modules to create the wrapped Neovim package.
neovimConfigured = inputs.nvf.lib.neovimConfiguration {
inherit pkgs;
modules = [
# Configuration module to be imported. You may define multiple modules
# or even import them from other files (e.g., ./modules/lsp.nix) to
# better modularize your configuration.
configModule
];
};
in {
# Packages to be exposed under packages.<system>. Those can accessed
# directly from package outputs in other flakes if this flake is added
# as an input. You may run those packages with 'nix run .#<package>'
default = self.packages.${system}.neovim;
neovimConfigured = neovimConfigured.neovim;
});
};
}

View file

@ -24,7 +24,7 @@ in {
entryAfter, and entryBefore to a topologically sorted list of
entries.
Internally this function uses the `toposort` function in
Internally this function uses the `topoSort` function in
`<nixpkgs/lib/lists.nix>` and its value is accordingly.
Specifically, the result on success is
@ -136,16 +136,26 @@ in {
entriesAfter = tag: entriesBetween tag [];
entriesBefore = tag: before: entriesBetween tag before [];
# mkLuarcSection and mkVimrcSection take a section DAG
# and return a string containing a comment to identify
# mkLuarcSection takes a section DAG, containing 'name' and 'data' fields
# then returns a string containing a comment to identify the section, and
# the data contained within the section.
# the section, and the data contained within the section
#
# all operations are done without any modifications
# to the inputted section data
mkLuarcSection = section: ''
-- SECTION: ${section.name}
${section.data}
'';
# All operations are done without any modifications to the inputted section
# data, but if a non-string is passed to name or data, then it will try to
# coerce it into a string, which may fail. Setting data to "" or null will
# return an empty string.
#
# section.data should never be null, though taking 'null' as a value that
# can "clear" the DAG might come in handy for filtering sections more easily.
# Or perhaps simply unsetting them from an user perspective.
mkLuarcSection = section:
if section.data == "" || section.data == null
then ""
else ''
-- SECTION: ${section.name}
${section.data}
'';
resolveDag = {
name,

View file

@ -1,10 +1,10 @@
{
self,
inputs,
lib,
...
}: {
types = import ./types {inherit inputs lib;};
types = import ./types {inherit lib self;};
config = import ./config.nix {inherit lib;};
binds = import ./binds.nix {inherit lib;};
dag = import ./dag.nix {inherit lib;};
@ -12,5 +12,5 @@
lists = import ./lists.nix {inherit lib;};
attrsets = import ./attrsets.nix {inherit lib;};
lua = import ./lua.nix {inherit lib;};
neovimConfiguration = import ../modules {inherit inputs lib;};
neovimConfiguration = import ../modules {inherit self inputs lib;};
}

View file

@ -1,10 +1,11 @@
# From home-manager: https://github.com/nix-community/home-manager/blob/master/modules/lib/booleans.nix
{lib}: let
inherit (builtins) isString getAttr;
inherit (lib.options) mkOption;
inherit (lib.types) bool;
inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) luaInline;
in {
# TODO: remove
diagnosticsToLua = {
lang,
config,
@ -32,4 +33,48 @@ in {
type = bool;
description = "Turn on ${desc} for enabled languages by default";
};
lspOptions = submodule {
freeformType = attrsOf anything;
options = {
enable = mkOption {
type = bool;
default = true;
description = "Whether to enable this LSP server.";
};
capabilities = mkOption {
type = nullOr (either luaInline (attrsOf anything));
default = null;
description = "LSP capabilitiess to pass to lspconfig";
};
on_attach = mkOption {
type = nullOr luaInline;
default = null;
description = "Function to execute when an LSP server attaches to a buffer";
};
filetypes = mkOption {
type = nullOr (listOf str);
default = null;
description = "Filetypes to auto-attach LSP in";
};
cmd = mkOption {
type = nullOr (listOf str);
default = null;
description = "Command used to start the LSP server";
};
root_markers = mkOption {
type = nullOr (listOf str);
default = null;
description = ''
"root markers" used to determine the root directory of the workspace, and
the filetypes associated with this LSP server.
'';
};
};
};
}

View file

@ -2,7 +2,7 @@
{lib}: let
inherit (builtins) hasAttr head throw typeOf isList isAttrs isBool isInt isString isPath isFloat toJSON;
inherit (lib.attrsets) mapAttrsToList filterAttrs;
inherit (lib.strings) concatStringsSep concatMapStringsSep stringToCharacters concatLines;
inherit (lib.strings) concatStringsSep concatMapStringsSep stringToCharacters;
inherit (lib.trivial) boolToString warn;
in rec {
# Convert a null value to lua's nil

View file

@ -1,6 +1,6 @@
# Convenience function that returns the given Nixpkgs standard library
# extended with our functions using `lib.extend`.
inputs:
{inputs, ...} @ args:
inputs.nixpkgs.lib.extend (self: super: {
# WARNING: New functions should not be added here, but to files
# imported by `./default.nix` under their own categories. If your
@ -12,7 +12,7 @@ inputs.nixpkgs.lib.extend (self: super: {
# E.g. for an input called `nvf`, `inputs.nvf.lib.nvim` will return the set
# below.
nvim = import ./. {
inherit inputs;
inherit (args) inputs self;
lib = self;
};

View file

@ -1,10 +1,9 @@
{
inputs,
lib,
...
self,
}: let
typesDag = import ./dag.nix {inherit lib;};
typesPlugin = import ./plugins.nix {inherit inputs lib;};
typesPlugin = import ./plugins.nix {inherit lib self;};
typesLanguage = import ./languages.nix {inherit lib;};
customTypes = import ./custom.nix {inherit lib;};
in {

View file

@ -1,12 +1,11 @@
{
inputs,
lib,
...
self,
}: let
inherit (lib.options) mkOption;
inherit (lib.attrsets) attrNames mapAttrs' filterAttrs nameValuePair;
inherit (lib.strings) hasPrefix removePrefix;
inherit (lib.types) submodule either package enum str lines attrsOf anything listOf nullOr;
inherit (lib.types) submodule either package enum str lines anything listOf nullOr;
# Get the names of all flake inputs that start with the given prefix.
fromInputs = {
@ -15,11 +14,8 @@
}:
mapAttrs' (n: v: nameValuePair (removePrefix prefix n) {src = v;}) (filterAttrs (n: _: hasPrefix prefix n) inputs);
# Get the names of all flake inputs that start with the given prefix.
pluginInputNames = attrNames (fromInputs {
inherit inputs;
prefix = "plugin-";
});
# Get the names of all npins
pluginInputNames = ["blink-cmp"] ++ attrNames self.pins;
# You can either use the name of the plugin or a package.
pluginType = nullOr (

View file

@ -1,4 +1,5 @@
{
self,
inputs,
lib,
}: {
@ -23,7 +24,7 @@
specialArgs =
extraSpecialArgs
// {
inherit inputs;
inherit self inputs;
modulesPath = toString ./.;
};
modules = concatLists [

View file

@ -4,6 +4,7 @@
inherit (lib.nvim.config) batchRenameOptions;
renamedVimOpts = batchRenameOptions ["vim"] ["vim" "options"] {
# 2024-12-01
colourTerm = "termguicolors";
mouseSupport = "mouse";
cmdHeight = "cmdheight";
@ -15,6 +16,9 @@
autoIndent = "autoindent";
wordWrap = "wrap";
showSignColumn = "signcolumn";
# 2025-02-07
scrollOffset = "scrolloff";
};
in {
imports = concatLists [
@ -93,9 +97,31 @@ in {
# 2024-12-02
(mkRenamedOptionModule ["vim" "enableEditorconfig"] ["vim" "globals" "editorconfig"])
# 2025-02-06
(mkRemovedOptionModule ["vim" "disableArrows"] ''
Top-level convenience options are now in the process of being removed from nvf as
their behaviour was abstract, and confusing. Please use 'vim.options' or 'vim.luaConfigRC'
to replicate previous behaviour.
'')
# 2025-04-04
(mkRemovedOptionModule ["vim" "lsp" "lsplines"] ''
lsplines module has been removed from nvf, as its functionality is now built into Neovim
under the diagnostics module. Please consider using one of 'vim.diagnostics.config' or
'vim.luaConfigRC' to configure LSP lines for Neovim through its own diagnostics API.
'')
# 2025-05-04
(mkRemovedOptionModule ["vim" "useSystemClipboard"] ''
Clipboard behaviour should now be controlled through the new, more fine-grained module
interface found in 'vim.clipboard'. To replicate previous behaviour, you may either
add 'vim.opt.clipboard:append("unnamedplus")' in luaConfigRC, or preferably set it
in 'vim.clipboard.registers'. Please see the documentation for the new module for more
details, or open an issue if you are confused.
'')
]
# 2024-12-01
# Migrated via batchRenameOptions. Further batch renames must be below this line.
renamedVimOpts
];

View file

@ -23,7 +23,9 @@
"completion"
"dashboard"
"debugger"
"diagnostics"
"filetree"
"formatter"
"git"
"languages"
"lsp"
@ -31,11 +33,12 @@
"minimap"
"notes"
"projects"
"repl"
"rich-presence"
"runner"
"session"
"snippets"
# "spellcheck" # FIXME: see neovim/init/spellcheck.nix
"spellcheck"
"statusline"
"tabline"
"terminal"

View file

@ -0,0 +1,188 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.lists) filter;
inherit (lib.strings) optionalString;
inherit (lib.types) nullOr submodule listOf str bool;
inherit (lib.nvim.types) luaInline;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAfter;
autocommandType = submodule {
options = {
enable =
mkEnableOption ""
// {
default = true;
description = "Whether to enable this autocommand.";
};
event = mkOption {
type = nullOr (listOf str);
default = null;
example = ["BufRead" "BufWritePre"];
description = "The event(s) that trigger the autocommand.";
};
pattern = mkOption {
type = nullOr (listOf str);
default = null;
example = ["*.lua" "*.vim"];
description = "The file pattern(s) that determine when the autocommand applies.";
};
callback = mkOption {
type = nullOr luaInline;
default = null;
example = literalExpression ''
lib.generators.mkLuaInline '''
function()
print("Saving a Lua file...")
end
''''
'';
description = "Lua function to be called when the event(s) are triggered.";
};
command = mkOption {
type = nullOr str;
default = null;
description = ''
Vim command to be executed when the event(s) are triggered.
Cannot be defined if the `callback` option is already defined.
'';
};
group = mkOption {
type = nullOr str;
default = null;
example = "MyAutoCmdGroup";
description = "An optional autocommand group to manage related autocommands.";
};
desc = mkOption {
type = nullOr str;
default = null;
example = "Notify when saving a Lua file";
description = "A description for the autocommand.";
};
once = mkOption {
type = bool;
default = false;
description = "Whether to run the autocommand only once.";
};
nested = mkOption {
type = bool;
default = false;
description = "Whether to allow nested autocommands to trigger.";
};
};
};
autogroupType = submodule {
options = {
enable =
mkEnableOption ""
// {
default = true;
description = "Whether to enable this autocommand group.";
};
name = mkOption {
type = str;
example = "MyAutoCmdGroup";
description = "The name of the autocommand group.";
};
clear = mkOption {
type = bool;
default = true;
description = ''
Whether to clear existing autocommands in this group before defining new ones.
This helps avoid duplicate autocommands.
'';
};
};
};
cfg = config.vim;
in {
options.vim = {
augroups = mkOption {
type = listOf autogroupType;
default = [];
description = ''
A list of Neovim autogroups, which are used to organize and manage related
autocommands together. Groups allow multiple autocommands to be cleared
or redefined collectively, preventing duplicate definitions.
Each autogroup consists of a name and a boolean indicating whether to clear
existing autocommands.
'';
};
autocmds = mkOption {
type = listOf autocommandType;
default = [];
description = ''
A list of Neovim autocommands to be registered.
Each entry defines an autocommand, specifying events, patterns, a callback or Vim
command, an optional group, a description, and execution settings.
'';
};
};
config = {
vim = let
enabledAutocommands = filter (cmd: cmd.enable) cfg.autocmds;
enabledAutogroups = filter (au: au.enable) cfg.augroups;
in {
luaConfigRC = {
augroups = entryAfter ["pluginConfigs"] (optionalString (enabledAutogroups != []) ''
local nvf_autogroups = {}
for _, group in ipairs(${toLuaObject enabledAutogroups}) do
if group.name then
nvf_autogroups[group.name] = { clear = group.clear }
end
end
for group_name, options in pairs(nvf_autogroups) do
vim.api.nvim_create_augroup(group_name, options)
end
'');
autocmds = entryAfter ["pluginConfigs"] (optionalString (enabledAutocommands != []) ''
local nvf_autocommands = ${toLuaObject enabledAutocommands}
for _, autocmd in ipairs(nvf_autocommands) do
vim.api.nvim_create_autocmd(
autocmd.event,
{
group = autocmd.group,
pattern = autocmd.pattern,
buffer = autocmd.buffer,
desc = autocmd.desc,
callback = autocmd.callback,
command = autocmd.command,
once = autocmd.once,
nested = autocmd.nested
}
)
end
'');
};
};
assertions = [
{
assertion = builtins.all (cmd: (cmd.command == null || cmd.callback == null)) cfg.autocmds;
message = "An autocommand cannot have both 'command' and 'callback' defined at the same time.";
}
];
};
}

View file

@ -6,46 +6,27 @@
inherit (lib.options) mkOption mkEnableOption literalMD;
inherit (lib.strings) optionalString;
inherit (lib.attrsets) optionalAttrs;
inherit (lib.types) enum bool str int either;
inherit (lib.types) enum bool str either;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.binds) pushDownDefault;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.types) luaInline;
cfg = config.vim;
in {
options.vim = {
disableArrows = mkOption {
type = bool;
default = false;
description = "Set to prevent arrow keys from moving cursor";
};
hideSearchHighlight = mkOption {
type = bool;
default = false;
description = "Hide search highlight so it doesn't stay highlighted";
};
scrollOffset = mkOption {
type = int;
default = 8;
description = "Start scrolling this number of lines from the top or bottom of the page.";
};
syntaxHighlighting = mkOption {
type = bool;
default = !config.vim.treesitter.highlight.enable;
description = "Enable syntax highlighting";
};
useSystemClipboard = mkOption {
type = bool;
default = false;
description = "Make use of the clipboard for default yank and paste operations. Don't use * and +";
};
lineNumberMode = mkOption {
type = enum ["relative" "number" "relNumber" "none"];
default = "relNumber";
@ -150,10 +131,6 @@ in {
# to pre-set Neovim options. Fear not, though as the Lua DAG is still as powerful as it
# could be.
luaConfigRC.basic = entryAfter ["globalsScript"] ''
${optionalString cfg.useSystemClipboard ''
vim.opt.clipboard:append("unnamedplus")
''}
${optionalString cfg.syntaxHighlighting ''
vim.cmd("syntax on")
''}

View file

@ -0,0 +1,80 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
inherit (lib.types) str submodule;
inherit (lib.attrsets) mapAttrs mapAttrsToList filterAttrs;
cfg = config.vim.clipboard;
in {
options = {
vim = {
clipboard = {
enable = mkEnableOption ''
clipboard management for Neovim. Users may still choose to manage their
clipboard through [](#opt-vim.options) should they wish to avoid using
this module.
'';
registers = mkOption {
type = str;
default = "";
example = "unnamedplus";
description = ''
The register to be used by the Neovim clipboard. Recognized types are:
* unnamed: Vim will use the clipboard register `"*"` for all yank, delete,
change and put operations which would normally go to the unnamed register.
* unnamedplus: A variant of the "unnamed" flag which uses the clipboard register
`"+"` ({command}`:h quoteplus`) instead of register `"*"` for all yank, delete,
change and put operations which would normally go to the unnamed register.
When `unnamed` and `unnamedplus` is included simultaneously as `"unnamed,unnamedplus"`,
yank and delete operations (but not put) will additionally copy the text into register `"*"`.
Please see {command}`:h clipboard` for more details.
'';
};
providers = mkOption {
type = submodule {
options = let
clipboards = {
# name = "package name";
wl-copy = "wl-clipboard";
xclip = "xclip";
xsel = "xsel";
};
in
mapAttrs (name: pname: {
enable = mkEnableOption name;
package = mkPackageOption pkgs pname {nullable = true;};
})
clipboards;
};
default = {};
description = ''
Clipboard providers for which packages will be added to nvf's
{option}`extraPackages`. The `package` field may be set to `null`
if related packages are already found in system packages to
potentially reduce closure sizes.
'';
};
};
};
};
config = mkIf cfg.enable {
vim = {
options.clipboard = cfg.registers;
extraPackages = mapAttrsToList (_: v: v.package) (
filterAttrs (_: v: v.enable && v.package != null) cfg.providers
);
};
};
}

View file

@ -1,8 +1,12 @@
{
imports = [
./autocmds.nix
./basic.nix
./clipboard.nix
./debug.nix
./diagnostics.nix
./highlight.nix
./lsp.nix
./spellcheck.nix
];
}

View file

@ -0,0 +1,116 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) attrsOf anything oneOf bool submodule;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.types) luaInline;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.diagnostics;
# Takes a boolean, a table, or a Lua list ({key = value}). We
# would like to allow all of those types, while clearly expressing
# them in the option's type. As such, this type is what it is.
diagnosticType = oneOf [(attrsOf anything) bool luaInline];
diagnosticsSubmodule = submodule {
# The table might need to be extended, so let's allow that case
# with a freeform type of what is supported by diagnostics opts.
freeformType = attrsOf diagnosticType;
options = {
underline = mkOption {
type = diagnosticType;
default = true;
description = "Use underline for diagnostics.";
};
virtual_text = mkOption {
type = diagnosticType;
default = false;
example = literalExpression ''
{
format = lib.generators.mkLuaInline '''
function(diagnostic)
return string.format("%s (%s)", diagnostic.message, diagnostic.source)
end
''';
}
'';
description = ''
Use virtual text for diagnostics. If multiple diagnostics are set for a namespace,
one prefix per diagnostic + the last diagnostic message are shown.
'';
};
virtual_lines = mkOption {
type = diagnosticType;
default = false;
description = ''
Use virtual lines for diagnostics.
'';
};
signs = mkOption {
type = diagnosticType;
default = false;
example = literalExpression ''
signs.text = lib.generators.mkLuaInline '''
{
[vim.diagnostic.severity.ERROR] = "󰅚 ",
[vim.diagnostic.severity.WARN] = "󰀪 ",
}
''';
'';
description = ''
Use signs for diagnostics. See {command}`:help diagnostic-signs`.
:::{.note}
The code presented in that example section uses Lua expressions as object keys which
only translate well if you use `lib.generators.mkLuaInline` as in the example.
:::
'';
};
update_in_insert = mkOption {
type = bool;
default = false;
description = ''
Update diagnostics in Insert mode. If `false`, diagnostics will
be updated on InsertLeave ({command}`:help InsertLeave`).
'';
};
};
};
in {
options.vim = {
diagnostics = {
enable = mkEnableOption "diagnostics module for Neovim";
config = mkOption {
type = diagnosticsSubmodule;
default = {};
description = ''
Values that will be passed to `vim.diagnostic.config` after being converted
to a Lua table. Possible values for each key can be found in the help text
for `vim.diagnostics.Opts`. You may find more about the diagnostics API of
Neovim in {command}`:help diagnostic-api`.
:::{.note}
This option is freeform. You may set values that are not present in nvf
documentation, but those values will not be fully type checked. Please
refer to the help text for `vim.diagnostic.Opts` for appropriate values.
:::
'';
};
};
};
config.vim = mkIf cfg.enable {
luaConfigRC.diagnostics = entryAfter ["basic"] ''
vim.diagnostic.config(${toLuaObject cfg.config})
'';
};
}

View file

@ -5,15 +5,14 @@
}: let
inherit (lib.options) mkOption;
inherit (lib.types) nullOr attrsOf listOf submodule bool ints str enum;
inherit (lib.strings) hasPrefix concatLines;
inherit (lib.strings) concatLines;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.nvim.dag) entryBetween;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.types) hexColor;
mkColorOption = target:
mkOption {
type = nullOr hexColor;
type = nullOr str;
default = null;
example = "#ebdbb2";
description = ''

View file

@ -0,0 +1,93 @@
{
config,
lib,
...
}: let
inherit (builtins) filter;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) attrsOf;
inherit (lib.strings) concatLines;
inherit (lib.attrsets) mapAttrsToList attrNames filterAttrs;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.languages) lspOptions;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp;
lspConfigurations =
mapAttrsToList (
name: value: ''
vim.lsp.config["${name}"] = ${toLuaObject value}
''
)
cfg.servers;
enabledServers = filterAttrs (_: u: u.enable) cfg.servers;
in {
options = {
vim.lsp = {
enable = mkEnableOption ''
global LSP functionality for Neovim.
This option controls whether to enable LSP functionality within modules under
{option}`vim.languages`. You do not need to set this to `true` for language
servers defined in {option}`vim.lsp.servers` to take effect, since they are
enabled automatically.
'';
servers = mkOption {
type = attrsOf lspOptions;
default = {};
example = ''
{
"*" = {
root_markers = [".git"];
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true;
};
};
};
};
"clangd" = {
filetypes = ["c"];
};
}
'';
description = ''
LSP configurations that will be managed using `vim.lsp.config()` and related
utilities added in Neovim 0.11. LSPs defined here will be added to the
resulting {file}`init.lua` using `vim.lsp.config` and enabled through
`vim.lsp.enable()` API from Neovim below the configuration table.
You may review the generated configuration by running {command}`nvf-print-config`
in a shell. Please see {command}`:help lsp-config` for more details
on the underlying API.
'';
};
};
};
config = mkMerge [
{
vim.lsp.servers."*" = {
capabilities = mkDefault (mkLuaInline "capabilities");
on_attach = mkDefault (mkLuaInline "default_on_attach");
};
}
(mkIf (cfg.servers != {}) {
vim.luaConfigRC.lsp-servers = entryAnywhere ''
-- Individual LSP configurations managed by nvf.
${concatLines lspConfigurations}
-- Enable configured LSPs explicitly
vim.lsp.enable(${toLuaObject (filter (name: name != "*") (attrNames enabledServers))})
'';
})
];
}

View file

@ -94,6 +94,8 @@ in {
Enabling this option will unconditionally set
{option}`vim.spellcheck.enable` to true as vim-dirtytalk
depends on spellchecking having been set up.
Run {command}`:DirtytalkUpdate` on first use to download the spellfile.
:::
'';
};

View file

@ -3,7 +3,7 @@
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.modules) mkMerge;
inherit (lib.trivial) pipe;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.lists) flatten;
@ -26,34 +26,6 @@
in {
config = {
vim.keymaps = mkMerge [
(
mkIf cfg.disableArrows [
{
key = "<up>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
}
{
key = "<down>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
}
{
key = "<left>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
}
{
key = "<right>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
}
]
)
(
pipe cfg.maps
[

View file

@ -0,0 +1,341 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption literalMD;
inherit (lib.types) int str enum nullOr attrs bool;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
options.vim.assistant = {
avante-nvim = {
enable = mkEnableOption "complementary Neovim plugin for avante.nvim";
setupOpts = mkPluginSetupOption "avante-nvim" {
provider = mkOption {
type = nullOr str;
default = null;
description = "The provider used in Aider mode or in the planning phase of Cursor Planning Mode.";
};
providers = mkOption {
type = nullOr attrs;
default = null;
description = "Define settings for builtin and custom providers.";
example = literalMD ''
```nix
openai = {
endpoint = "https://api.openai.com/v1";
model = "gpt-4o"; # your desired model (or use gpt-4o, etc.)
timeout = 30000; # Timeout in milliseconds, increase this for reasoning models
extra_request_body = {
temperature = 0;
max_completion_tokens = 8192; # Increase this to include reasoning tokens (for reasoning models)
reasoning_effort = "medium"; # low|medium|high, only used for reasoning models
};
};
ollama = {
endpoint = "http://127.0.0.1:11434";
timeout = 30000; # Timeout in milliseconds
extra_request_body = {
options = {
temperature = 0.75;
num_ctx = 20480;
keep_alive = "5m";
};
};
};
groq = {
__inherited_from = "openai";
api_key_name = "GROQ_API_KEY";
endpoint = "https://api.groq.com/openai/v1/";
model = "llama-3.3-70b-versatile";
disable_tools = true;
extra_request_body = {
temperature = 1;
max_tokens = 32768; # remember to increase this value, otherwise it will stop generating halfway
};
};
```
'';
};
auto_suggestions_provider = mkOption {
type = str;
default = "claude";
description = ''
Since auto-suggestions are a high-frequency operation and therefore expensive,
currently designating it as `copilot` provider is dangerous because:
https://github.com/yetone/avante.nvim/issues/1048
Of course, you can reduce the request frequency by increasing `suggestion.debounce`.
'';
};
cursor_applying_provider = mkOption {
type = nullOr str;
default = null;
description = ''
The provider used in the applying phase of Cursor Planning Mode, defaults to `nil`,
Config.provider will be used as the provider for the applying phase when `nil`.
'';
};
dual_boost = {
enabled = mkEnableOption "dual_boost mode.";
first_provider = mkOption {
type = str;
default = "openai";
description = "The first provider to generate response.";
};
second_provider = mkOption {
type = str;
default = "claude";
description = "The second provider to generate response.";
};
prompt = mkOption {
type = str;
default = ''
Based on the two reference outputs below, generate a response that incorporates
elements from both but reflects your own judgment and unique perspective.
Do not provide any explanation, just give the response directly. Reference Output 1:
[{{provider1_output}}], Reference Output 2: [{{provider2_output}}'';
description = "The prompt to generate response based on the two reference outputs.";
};
timeout = mkOption {
type = int;
default = 60000;
description = "Timeout in milliseconds.";
};
};
behaviour = {
auto_suggestions =
mkEnableOption "auto suggestions.";
auto_set_highlight_group =
mkEnableOption "automatically set the highlight group for the current line."
// {
default = true;
};
auto_set_keymaps =
mkEnableOption "automatically set the keymap for the current line."
// {
default = true;
};
auto_apply_diff_after_generation =
mkEnableOption "automatically apply diff after LLM response.";
support_paste_from_clipboard = mkEnableOption ''
pasting image from clipboard.
This will be determined automatically based whether img-clip is available or not.
'';
minimize_diff =
mkEnableOption "remove unchanged lines when applying a code block."
// {
default = true;
};
enable_token_counting =
mkEnableOption "token counting."
// {
default = true;
};
enable_cursor_planning_mode =
mkEnableOption "Cursor Planning Mode.";
enable_claude_text_editor_tool_mode =
mkEnableOption "Claude Text Editor Tool Mode.";
};
mappings = {
diff = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for diff.";
};
suggestion = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for suggestion actions.";
};
jump = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for jump actions.";
};
submit = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for submit actions.";
};
cancel = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for cancel actions.";
};
sidebar = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps for sidebar actions.";
};
};
hints.enabled =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable hints.
'';
};
windows = {
position = mkOption {
type = enum ["right" "left" "top" "bottom"];
default = "right";
description = "The position of the sidebar.";
};
wrap =
mkEnableOption ""
// {
default = true;
description = ''
similar to vim.o.wrap.
'';
};
width = mkOption {
type = int;
default = 30;
description = "Default % based on available width.";
};
sidebar_header = {
enabled = mkOption {
type = bool;
default = true;
description = "enable/disable the header.";
};
align = mkOption {
type = enum ["right" "center" "left"];
default = "center";
description = "Position of the title.";
};
rounded = mkOption {
type = bool;
default = true;
description = "Enable rounded sidebar header";
};
};
input = {
prefix = mkOption {
type = str;
default = "> ";
description = "The prefix used on the user input.";
};
height = mkOption {
type = int;
default = 8;
description = ''
Height of the input window in vertical layout.
'';
};
};
edit = {
border = mkOption {
type = str;
default = "rounded";
description = "The border type on the edit window.";
};
start_insert = mkOption {
type = bool;
default = true;
description = ''
Start insert mode when opening the edit window.
'';
};
};
ask = {
floating = mkOption {
type = bool;
default = false;
description = ''
Open the 'AvanteAsk' prompt in a floating window.
'';
};
start_insert = mkOption {
type = bool;
default = true;
description = ''
Start insert mode when opening the ask window.
'';
};
border = mkOption {
type = str;
default = "rounded";
description = "The border type on the ask window.";
};
focus_on_apply = mkOption {
type = enum ["ours" "theirs"];
default = "ours";
description = "Which diff to focus after applying.";
};
};
};
diff = {
autojump =
mkEnableOption ""
// {
default = true;
description = "Automatically jumps to the next change.";
};
override_timeoutlen = mkOption {
type = int;
default = 500;
example = -1;
description = ''
Override the 'timeoutlen' setting while hovering over a diff (see {command}`:help timeoutlen`).
Helps to avoid entering operator-pending mode with diff mappings starting with `c`.
Disable by setting to -1.
'';
};
};
suggestion = {
debounce = mkOption {
type = int;
default = 600;
description = "Suggestion debounce in milliseconds.";
};
throttle = mkOption {
type = int;
default = 600;
description = "Suggestion throttle in milliseconds.";
};
};
};
};
};
}

View file

@ -0,0 +1,41 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.lists) optionals;
cfg = config.vim.assistant.avante-nvim;
in {
config = mkIf cfg.enable {
vim = {
startPlugins =
[
"nvim-treesitter"
"plenary-nvim"
"dressing-nvim"
"nui-nvim"
]
++ (optionals config.vim.mini.pick.enable ["mini-pick"])
++ (optionals config.vim.telescope.enable ["telescope"])
++ (optionals config.vim.autocomplete.nvim-cmp.enable ["nvim-cmp"])
++ (optionals config.vim.fzf-lua.enable ["fzf-lua"])
++ (optionals config.vim.visuals.nvim-web-devicons.enable ["nvim-web-devicons"])
++ (optionals config.vim.utility.images.img-clip.enable ["img-clip"]);
lazy.plugins = {
avante-nvim = {
package = "avante-nvim";
setupModule = "avante";
inherit (cfg) setupOpts;
event = ["DeferredUIEnter"];
};
};
treesitter.enable = true;
languages.markdown.extensions.render-markdown-nvim.setupOpts.file_types = lib.mkAfter ["Avante"];
};
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./config.nix
./avante-nvim.nix
];
}

View file

@ -31,16 +31,27 @@ in {
config = mkIf cfg.enable {
vim = {
startPlugins = [
"chatgpt"
"chatgpt-nvim"
# Dependencies
"nui-nvim"
"plenary-nvim"
];
# ChatGPT.nvim explicitly depends on Telescope.
telescope.enable = true;
pluginRC.chagpt = entryAnywhere ''
require("chatgpt").setup(${toLuaObject cfg.setupOpts})
'';
maps.normal = mkMerge [
(mkSetBinding mappings.chatGpt "<cmd>ChatGPT<CR>")
maps
];
maps.visual = maps;
maps = {
visual = maps;
normal = mkMerge [
(mkSetBinding mappings.chatGpt "<cmd>ChatGPT<CR>")
maps
];
};
};
};
}

View file

@ -0,0 +1,301 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) int str enum nullOr attrs;
inherit (lib.nvim.types) mkPluginSetupOption luaInline;
in {
options.vim.assistant = {
codecompanion-nvim = {
enable = mkEnableOption "complementary neovim plugin for codecompanion.nvim";
setupOpts = mkPluginSetupOption "codecompanion-nvim" {
opts = {
send_code =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable code being sent to the LLM.
'';
};
log_level = mkOption {
type = enum ["DEBUG" "INFO" "ERROR" "TRACE"];
default = "ERROR";
description = "Change the level of logging.";
};
language = mkOption {
type = str;
default = "English";
description = "Specify which language an LLM should respond in.";
};
};
display = {
diff = {
enabled =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable a diff view
to see the changes made by the LLM.
'';
};
close_chat_at = mkOption {
type = int;
default = 240;
description = ''
Close an open chat buffer if the
total columns of your display are less than...
'';
};
layout = mkOption {
type = enum ["vertical" "horizontal"];
default = "vertical";
description = "Type of split for default provider.";
};
provider = mkOption {
type = enum ["default" "mini_diff"];
default = "default";
description = "The preferred kind of provider.";
};
};
inline = {
layout = mkOption {
type = enum ["vertical" "horizontal" "buffer"];
default = "vertical";
description = "Customize how output is created in new buffer.";
};
};
chat = {
auto_scroll =
mkEnableOption ""
// {
default = true;
description = "Whether to enable automatic page scrolling.";
};
show_settings = mkEnableOption ''
LLM settings to appear at the top of the chat buffer.
'';
start_in_insert_mode = mkEnableOption ''
opening the chat buffer in insert mode.
'';
show_header_separator = mkEnableOption ''
header separators in the chat buffer.
Set this to false if you're using an
external markdown formatting plugin.
'';
show_references =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable references in the chat buffer.
'';
};
show_token_count =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable the token count for each response.
'';
};
intro_message = mkOption {
type = str;
default = "Welcome to CodeCompanion ! Press ? for options.";
description = "Message to appear in chat buffer.";
};
separator = mkOption {
type = str;
default = "";
description = ''
The separator between the
different messages in the chat buffer.
'';
};
icons = {
pinned_buffer = mkOption {
type = str;
default = " ";
description = "The icon to represent a pinned buffer.";
};
watched_buffer = mkOption {
type = str;
default = "👀 ";
description = "The icon to represent a watched buffer.";
};
};
};
action_palette = {
width = mkOption {
type = int;
default = 95;
description = "Width of the action palette.";
};
height = mkOption {
type = int;
default = 10;
description = "Height of the action palette.";
};
prompt = mkOption {
type = str;
default = "Prompt ";
description = "Prompt used for interactive LLM calls.";
};
provider = mkOption {
type = enum ["default" "telescope" "mini_pick"];
default = "default";
description = "Provider used for the action palette.";
};
opts = {
show_default_actions =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable showing default
actions in the action palette.
'';
};
show_default_prompt_library =
mkEnableOption ""
// {
default = true;
description = ''
Whether to enable showing default
prompt library in the action palette.
'';
};
};
};
};
adapters = mkOption {
type = nullOr luaInline;
default = null;
description = "An adapter is what connects Neovim to an LLM.";
};
strategies = {
chat = {
adapter = mkOption {
type = nullOr str;
default = null;
description = "Adapter used for the chat strategy.";
};
keymaps = mkOption {
type = nullOr attrs;
default = null;
description = "Define or override the default keymaps.";
};
variables = mkOption {
type = nullOr luaInline;
default = null;
description = ''
Define your own variables
to share specific content.
'';
};
slash_commands = mkOption {
type = nullOr luaInline;
default = null;
description = ''
Slash Commands (invoked with /) let you dynamically
insert context into the chat buffer,
such as file contents or date/time.
'';
};
tools = mkOption {
type = nullOr attrs;
default = null;
description = ''
Configure tools to perform specific
tasks when invoked by an LLM.
'';
};
roles = mkOption {
type = nullOr luaInline;
default = null;
description = ''
The chat buffer places user and LLM responses under a H2 header.
These can be customized in the configuration.
'';
};
};
inline = {
adapter = mkOption {
type = nullOr str;
default = null;
description = "Adapter used for the inline strategy.";
};
variables = mkOption {
type = nullOr luaInline;
default = null;
description = ''
Define your own variables
to share specific content.
'';
};
keymaps = {
accept_change = {
n = mkOption {
type = str;
default = "ga";
description = "Accept the suggested change.";
};
};
reject_change = {
n = mkOption {
type = str;
default = "gr";
description = "Reject the suggested change.";
};
};
};
};
};
prompt_library = mkOption {
type = nullOr attrs;
default = null;
description = ''
A prompt library is a collection of prompts
that can be used in the action palette.
'';
};
};
};
};
}

View file

@ -0,0 +1,42 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.vim.assistant.codecompanion-nvim;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = [
"plenary-nvim"
];
lazy.plugins = {
codecompanion-nvim = {
package = "codecompanion-nvim";
setupModule = "codecompanion";
inherit (cfg) setupOpts;
};
};
treesitter = {
enable = true;
# Codecompanion depends on the YAML grammar being added. Below is
# an easy way of adding an user-configurable grammar package exposed
# by the YAML language module *without* enabling the whole YAML language
# module. The package is defined even when the module is disabled.
grammars = [
config.vim.languages.yaml.treesitter.package
];
};
autocomplete.nvim-cmp = {
sources = {codecompanion-nvim = "[codecompanion]";};
sourcePlugins = ["codecompanion-nvim"];
};
};
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./config.nix
./codecompanion-nvim.nix
];
}

View file

@ -5,7 +5,6 @@
}: let
inherit (builtins) toJSON;
inherit (lib.modules) mkIf;
inherit (lib.strings) optionalString;
cfg = config.vim.assistant.copilot;
@ -37,6 +36,12 @@ in {
inherit (cfg) setupOpts;
after = mkIf cfg.cmp.enable "require('copilot_cmp').setup()";
event = [
{
event = "User";
pattern = "LazyFile";
}
];
cmd = ["Copilot" "CopilotAuth" "CopilotDetach" "CopilotPanel" "CopilotStop"];
keys = [
(mkLuaKeymap ["n"] cfg.mappings.panel.accept (wrapPanelBinding ''require("copilot.panel").accept'' cfg.mappings.panel.accept) "[copilot] Accept suggestion" {})

View file

@ -2,5 +2,8 @@
imports = [
./chatgpt
./copilot
./codecompanion
./supermaven-nvim
./avante
];
}

View file

@ -0,0 +1,17 @@
{
config,
lib,
...
}: let
cfg = config.vim.assistant.supermaven-nvim;
in {
config = lib.mkIf cfg.enable {
vim.lazy.plugins = {
supermaven-nvim = {
package = "supermaven-nvim";
setupModule = "supermaven-nvim";
inherit (cfg) setupOpts;
};
};
};
}

View file

@ -0,0 +1,6 @@
{
imports = [
./supermaven-nvim.nix
./config.nix
];
}

Some files were not shown because too many files have changed in this diff Show more