diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index de6ff5ef..2fb071ca 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -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 diff --git a/.github/README.md b/.github/README.md index 7c0974c3..3fc7ffdf 100644 --- a/.github/README.md +++ b/.github/README.md @@ -200,8 +200,9 @@ fix. **Q**: What platforms are supported? **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. +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_? @@ -246,14 +247,15 @@ Neovim's behaviour with Nix. ### 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 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. @@ -270,14 +272,14 @@ 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! @@ -301,7 +303,6 @@ including: I am grateful for their previous work and inspiration, and I wholeheartedly recommend checking their work out. -
## License diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 00000000..34c3bf2c --- /dev/null +++ b/.github/labels.yml @@ -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 diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 00000000..0a558fb8 --- /dev/null +++ b/.github/workflows/backport.yml @@ -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@v4 + 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+)?)$' diff --git a/.github/workflows/cachix.yml b/.github/workflows/cachix.yml index cac8ee51..959a04b6 100644 --- a/.github/workflows/cachix.yml +++ b/.github/workflows/cachix.yml @@ -36,7 +36,7 @@ jobs: - name: Install Nix uses: DeterminateSystems/nix-installer-action@main - - uses: cachix/cachix-action@v15 + - uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_TOKEN }} extraPullNames: nix-community diff --git a/.github/workflows/check-docs.yml b/.github/workflows/check-docs.yml deleted file mode 100644 index 4d133ecd..00000000 --- a/.github/workflows/check-docs.yml +++ /dev/null @@ -1,56 +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 - - - 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 - - - name: Checkout - uses: actions/checkout@v4 - - - name: Build documentation packages - run: nix build .#docs-linkcheck -Lv diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 7a7677eb..a3f4fce3 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -1,4 +1,6 @@ -name: "Validate flake & check formatting" +name: "Treewide Checks" +permissions: read-all + on: pull_request: workflow_dispatch: @@ -6,13 +8,13 @@ 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 @@ -24,8 +26,9 @@ jobs: 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 @@ -33,4 +36,118 @@ jobs: - name: Install Nix uses: DeterminateSystems/nix-installer-action@main - - run: nix run nixpkgs#alejandra -- -c . + - name: Check formatting via Alejandra + run: nix run nixpkgs#alejandra -- --check . --exclude npins + + 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@v4 + + - 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@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 + if: "!contains(github.event.pull_request.title, '[skip ci]')" + steps: + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + + - name: Checkout + uses: actions/checkout@v4 + + - 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@v4 + 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' + + - 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 diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index 204dcba7..aa8fb272 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -1,9 +1,13 @@ -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 @@ -13,7 +17,7 @@ jobs: uses: actions/checkout@v4 - 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" diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml index f8f45d05..9adaf5ef 100644 --- a/.github/workflows/docs-preview.yml +++ b/.github/workflows/docs-preview.yml @@ -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 @@ -34,7 +34,7 @@ jobs: 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: | diff --git a/.github/workflows/editorconfig.yml b/.github/workflows/editorconfig.yml deleted file mode 100644 index 3d8ca360..00000000 --- a/.github/workflows/editorconfig.yml +++ /dev/null @@ -1,46 +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 - - - 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 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000..fc2e0d65 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -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@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: .github/labels.yml + sync-labels: true diff --git a/.github/workflows/typos.yml b/.github/workflows/typos.yml deleted file mode 100644 index d74ee5b7..00000000 --- a/.github/workflows/typos.yml +++ /dev/null @@ -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 diff --git a/configuration.nix b/configuration.nix index 692337db..6e3175ef 100644 --- a/configuration.nix +++ b/configuration.nix @@ -18,14 +18,17 @@ 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; }; @@ -39,8 +42,7 @@ 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; + enableFormat = true; # enableTreesitter = true; enableExtraDiagnostics = true; @@ -82,6 +84,7 @@ isMaximal: { elixir.enable = false; haskell.enable = false; ruby.enable = false; + fsharp.enable = false; tailwind.enable = false; svelte.enable = false; @@ -124,7 +127,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 = { @@ -142,6 +153,7 @@ isMaximal: { binds = { whichKey.enable = true; cheatsheet.enable = true; + hardtime-nvim.enable = isMaximal; }; telescope.enable = true; @@ -234,6 +246,7 @@ isMaximal: { enable = false; cmp.enable = isMaximal; }; + codecompanion-nvim.enable = false; }; session = { diff --git a/docs/default.nix b/docs/default.nix index 48cff563..49f90b80 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -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 = diff --git a/docs/manual/configuring.md b/docs/manual/configuring.md index f891c7a6..28c7e66a 100644 --- a/docs/manual/configuring.md +++ b/docs/manual/configuring.md @@ -1,5 +1,15 @@ # 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](/options.html) + ```{=include=} chapters configuring/custom-package.md configuring/custom-plugins.md @@ -7,4 +17,5 @@ configuring/overriding-plugins.md configuring/languages.md configuring/dags.md configuring/dag-entries.md +configuring/autocmds.md ``` diff --git a/docs/manual/configuring/autocmds.md b/docs/manual/configuring/autocmds.md new file mode 100644 index 00000000..be10e726 --- /dev/null +++ b/docs/manual/configuring/autocmds.md @@ -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.nvim.types.luaInline` or `lib.options.literalExpression "mkLuaInline '''...'''"`. **Cannot be used with `command`.** | `lib.nvim.types.luaInline "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.nvim.types.luaInline '' + 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. diff --git a/docs/manual/configuring/custom-package.md b/docs/manual/configuring/custom-package.md index 51d996b6..3e9e324a 100644 --- a/docs/manual/configuring/custom-package.md +++ b/docs/manual/configuring/custom-package.md @@ -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; } ``` diff --git a/docs/manual/configuring/custom-plugins.md b/docs/manual/configuring/custom-plugins.md index 79a691e2..bf986a0f 100644 --- a/docs/manual/configuring/custom-plugins.md +++ b/docs/manual/configuring/custom-plugins.md @@ -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 diff --git a/docs/manual/configuring/custom-plugins/configuring.md b/docs/manual/configuring/custom-plugins/configuring.md index c0935f03..a4b3ce19 100644 --- a/docs/manual/configuring/custom-plugins/configuring.md +++ b/docs/manual/configuring/custom-plugins/configuring.md @@ -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')"; } ``` +[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. ::: - diff --git a/docs/manual/configuring/custom-plugins/lazy-method.md b/docs/manual/configuring/custom-plugins/lazy-method.md index c6fd7106..c16966b8 100644 --- a/docs/manual/configuring/custom-plugins/lazy-method.md +++ b/docs/manual/configuring/custom-plugins/lazy-method.md @@ -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"]` diff --git a/docs/manual/configuring/custom-plugins/legacy-method.md b/docs/manual/configuring/custom-plugins/legacy-method.md index b2bddf43..6c399aaf 100644 --- a/docs/manual/configuring/custom-plugins/legacy-method.md +++ b/docs/manual/configuring/custom-plugins/legacy-method.md @@ -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 diff --git a/docs/manual/configuring/custom-plugins/non-lazy-method.md b/docs/manual/configuring/custom-plugins/non-lazy-method.md index 351af2eb..24ef7688 100644 --- a/docs/manual/configuring/custom-plugins/non-lazy-method.md +++ b/docs/manual/configuring/custom-plugins/non-lazy-method.md @@ -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. diff --git a/docs/manual/configuring/languages.md b/docs/manual/configuring/languages.md index 74714365..252163fb 100644 --- a/docs/manual/configuring/languages.md +++ b/docs/manual/configuring/languages.md @@ -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. diff --git a/docs/manual/configuring/languages/lsp.md b/docs/manual/configuring/languages/lsp.md index 6d6ed5bc..2ddc08b5 100644 --- a/docs/manual/configuring/languages/lsp.md +++ b/docs/manual/configuring/languages/lsp.md @@ -1,17 +1,22 @@ # LSP Custom Packages/Command {#sec-languages-custom-lsp-packages} -In any of the `opt.languages..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"]; }; } diff --git a/docs/manual/default-configs.md b/docs/manual/default-configs.md deleted file mode 100644 index 96ffa81a..00000000 --- a/docs/manual/default-configs.md +++ /dev/null @@ -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 -``` diff --git a/docs/manual/default-configs/maximal.md b/docs/manual/default-configs/maximal.md deleted file mode 100644 index 36887633..00000000 --- a/docs/manual/default-configs/maximal.md +++ /dev/null @@ -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. ::: diff --git a/docs/manual/default-configs/nix.md b/docs/manual/default-configs/nix.md deleted file mode 100644 index 5210ef39..00000000 --- a/docs/manual/default-configs/nix.md +++ /dev/null @@ -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. diff --git a/docs/manual/installation/custom-configuration.md b/docs/manual/installation/custom-configuration.md index 940f35a3..52f81573 100644 --- a/docs/manual/installation/custom-configuration.md +++ b/docs/manual/installation/custom-configuration.md @@ -39,7 +39,7 @@ An example flake that exposes your custom Neovim configuration might look like 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. diff --git a/docs/manual/manual.md b/docs/manual/manual.md index fd225766..18932896 100644 --- a/docs/manual/manual.md +++ b/docs/manual/manual.md @@ -8,7 +8,6 @@ try-it-out.md ``` ```{=include=} parts -default-configs.md installation.md configuring.md tips.md diff --git a/docs/manual/options.md b/docs/manual/options.md index 61282dfa..beab4f16 100644 --- a/docs/manual/options.md +++ b/docs/manual/options.md @@ -5,8 +5,8 @@ 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 us know if you believe any of the -options below are missing useful examples. +which you can access with `man 5 nvf`. Please let us know if you believe any of +the options below are missing useful examples.