Merge branch 'v0.8' into main

This commit is contained in:
Krapp 2025-11-26 14:50:09 -03:00 committed by GitHub
commit e63f8f4f33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
100 changed files with 4051 additions and 2065 deletions

View file

@ -1,11 +1,7 @@
version: 2 version: 2
updates: updates:
- package-ecosystem: github-actions - package-ecosystem: github-actions
open-pull-requests-limit: 15
directory: "/" directory: "/"
schedule: schedule:
interval: daily interval: daily
open-pull-requests-limit: 15
reviewers:
- NotAShelf
assignees:
- NotAShelf

3
.github/typos.toml vendored
View file

@ -6,6 +6,9 @@ default.extend-ignore-words-re = [
"annote", "annote",
"viw", "viw",
"typ", "typ",
"edn",
"esy",
"BA", # somehow "BANanaD3V" is valid, but BA is not... "BA", # somehow "BANanaD3V" is valid, but BA is not...
"Emac"
] ]

91
.github/workflows/update.yml vendored Normal file
View file

@ -0,0 +1,91 @@
name: Weekly Dependency Updates
on:
workflow_dispatch:
schedule:
# 8 PM UTC every Friday
- cron: '0 20 * * 5'
jobs:
update-dependencies:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: "Install Nix"
uses: cachix/install-nix-action@v31.8.2
- name: Set up Git
run: |
git config user.name "GitHub Actions Bot"
git config user.email "actions@github.com"
- name: Create branch for updates
run: |
DATE=$(date +%Y-%m-%d)
BRANCH_NAME="update/dependencies-$DATE"
git checkout -b $BRANCH_NAME
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
- name: Update npins
run: nix run nixpkgs#npins update
# Only update Nixpkgs. mnw might break on update, better to track it manually to avoid
# unexpected breakage.
- name: Update nixpkgs
run: nix flake update nixpkgs
- name: Check for changes
id: check_changes
run: |
if git diff --quiet; then
echo "No changes detected"
echo "changes_detected=false" >> "$GITHUB_OUTPUT"
exit 0
else
echo "Changes detected"
echo "changes_detected=true" >> "$GITHUB_OUTPUT"
fi
# FIXME: Worth adding additional checks for, e.g., fragile plugins
# or modules
# nix build .#checks.<system>.<check-name>
# We'll probably want to handle this with machine tests
- name: Verify changes
if: steps.check_changes.outputs.changes_detected == 'true'
run: |
# Run verification tests to ensure updates don't break anything
nix flake check
- name: Set date variable
run: echo "DATE=$(date +%Y-%m-%d)" >> "$GITHUB_ENV"
- name: Commit and push changes
if: steps.check_changes.outputs.changes_detected == 'true'
run: |
git add .
git commit -m "pins: bump all plugins (${{ env.DATE }})"
git push -u origin $BRANCH_NAME
- name: Create Pull Request
if: steps.check_changes.outputs.changes_detected == 'true'
uses: peter-evans/create-pull-request@v7
with:
branch: ${{ env.BRANCH_NAME }}
base: main
labels: dependencies,automated pr
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "npins: bump all plugins (${{ env.DATE }})"
title: "Weekly Dependency Updates: ${{ env.DATE }}"
body: |
> [!NOTE]
> This PR was automatically generated by the Weekly Dependency Updates workflow. Please wait
> for all CI steps to complete, and test any major changes personally.
Updates Performed:
- Updated dependencies using `npins update`
- Updated nixpkgs using `nix flake update nixpkgs`
If the verification steps have passed, updates should be safe to merge. For failing CI steps
submit a Pull Request targetting ${{ env.BRANCH_NAME }}

View file

@ -31,6 +31,7 @@ isMaximal: {
lspSignature.enable = !isMaximal; # conflicts with blink in maximal lspSignature.enable = !isMaximal; # conflicts with blink in maximal
otter-nvim.enable = isMaximal; otter-nvim.enable = isMaximal;
nvim-docs-view.enable = isMaximal; nvim-docs-view.enable = isMaximal;
harper-ls.enable = isMaximal;
}; };
debugger = { debugger = {
@ -56,6 +57,7 @@ isMaximal: {
clang.enable = isMaximal; clang.enable = isMaximal;
css.enable = isMaximal; css.enable = isMaximal;
html.enable = isMaximal; html.enable = isMaximal;
json.enable = isMaximal;
sql.enable = isMaximal; sql.enable = isMaximal;
java.enable = isMaximal; java.enable = isMaximal;
kotlin.enable = isMaximal; kotlin.enable = isMaximal;
@ -67,7 +69,7 @@ isMaximal: {
typst.enable = isMaximal; typst.enable = isMaximal;
rust = { rust = {
enable = isMaximal; enable = isMaximal;
crates.enable = isMaximal; extensions.crates-nvim.enable = isMaximal;
}; };
# Language modules that are not as common. # Language modules that are not as common.
@ -84,8 +86,11 @@ isMaximal: {
ocaml.enable = false; ocaml.enable = false;
elixir.enable = false; elixir.enable = false;
haskell.enable = false; haskell.enable = false;
hcl.enable = false;
ruby.enable = false; ruby.enable = false;
fsharp.enable = false; fsharp.enable = false;
just.enable = false;
qml.enable = false;
tailwind.enable = false; tailwind.enable = false;
svelte.enable = false; svelte.enable = false;
@ -188,6 +193,7 @@ isMaximal: {
vim-wakatime.enable = false; vim-wakatime.enable = false;
diffview-nvim.enable = true; diffview-nvim.enable = true;
yanky-nvim.enable = false; yanky-nvim.enable = false;
qmk-nvim.enable = false; # requires hardware specific options
icon-picker.enable = isMaximal; icon-picker.enable = isMaximal;
surround.enable = isMaximal; surround.enable = isMaximal;
leetcode-nvim.enable = isMaximal; leetcode-nvim.enable = isMaximal;

View file

@ -1,10 +1,10 @@
# Language Support {#ch-languages} # Language Support {#ch-languages}
Language specific support means there is a combination of language specific Language specific support means there is a combination of language specific
plugins, `treesitter` support, `nvim-lspconfig` language servers, and `null-ls` plugins, `treesitter` support, `nvim-lspconfig` language servers, `conform-nvim`
integration. This gets you capabilities ranging from autocompletion to formatters, and `nvim-lint` linter integration. This gets you capabilities
formatting to diagnostics. The following languages have sections under the ranging from autocompletion to formatting to diagnostics. The following
`vim.languages` attribute. languages have sections under the `vim.languages` attribute.
- Rust: [vim.languages.rust.enable](#opt-vim.languages.rust.enable) - Rust: [vim.languages.rust.enable](#opt-vim.languages.rust.enable)
- Nix: [vim.languages.nix.enable](#opt-vim.languages.nix.enable) - Nix: [vim.languages.nix.enable](#opt-vim.languages.nix.enable)
@ -20,6 +20,35 @@ formatting to diagnostics. The following languages have sections under the
- Lua: [vim.languages.lua.enable](#opt-vim.languages.lua.enable) - Lua: [vim.languages.lua.enable](#opt-vim.languages.lua.enable)
- PHP: [vim.languages.php.enable](#opt-vim.languages.php.enable) - PHP: [vim.languages.php.enable](#opt-vim.languages.php.enable)
- F#: [vim.languages.fsharp.enable](#opt-vim.languages.fsharp.enable) - F#: [vim.languages.fsharp.enable](#opt-vim.languages.fsharp.enable)
- Assembly: [vim.languages.assembly.enable](#opt-vim.languages.assembly.enable)
- Astro: [vim.languages.astro.enable](#opt-vim.languages.astro.enable)
- Bash: [vim.languages.bash.enable](#opt-vim.languages.bash.enable)
- Clang: [vim.languages.clang.enable](#opt-vim.languages.clang.enable)
- Clojure: [vim.languages.clojure.enable](#opt-vim.languages.clojure.enable)
- C#: [vim.languages.csharp.enable](#opt-vim.languages.csharp.enable)
- CSS: [vim.languages.css.enable](#opt-vim.languages.css.enable)
- CUE: [vim.languages.cue.enable](#opt-vim.languages.cue.enable)
- Elixir: [vim.languages.elixir.enable](#opt-vim.languages.elixir.enable)
- Gleam: [vim.languages.gleam.enable](#opt-vim.languages.gleam.enable)
- HCL: [vim.languages.hcl.enable](#opt-vim.languages.hcl.enable)
- Helm: [vim.languages.helm.enable](#opt-vim.languages.helm.enable)
- Julia: [vim.languages.julia.enable](#opt-vim.languages.julia.enable)
- Kotlin: [vim.languages.kotlin.enable](#opt-vim.languages.kotlin.enable)
- Nim: [vim.languages.nim.enable](#opt-vim.languages.nim.enable)
- Nu: [vim.languages.nu.enable](#opt-vim.languages.nu.enable)
- OCaml: [vim.languages.ocaml.enable](#opt-vim.languages.ocaml.enable)
- Odin: [vim.languages.odin.enable](#opt-vim.languages.odin.enable)
- R: [vim.languages.r.enable](#opt-vim.languages.r.enable)
- Ruby: [vim.languages.ruby.enable](#opt-vim.languages.ruby.enable)
- Scala: [vim.languages.scala.enable](#opt-vim.languages.scala.enable)
- Svelte: [vim.languages.svelte.enable](#opt-vim.languages.svelte.enable)
- Tailwind: [vim.languages.tailwind.enable](#opt-vim.languages.tailwind.enable)
- Terraform:
[vim.languages.terraform.enable](#opt-vim.languages.terraform.enable)
- Typst: [vim.languages.typst.enable](#opt-vim.languages.typst.enable)
- Vala: [vim.languages.vala.enable](#opt-vim.languages.vala.enable)
- WGSL: [vim.languages.wgsl.enable](#opt-vim.languages.wgsl.enable)
- YAML: [vim.languages.yaml.enable](#opt-vim.languages.yaml.enable)
Adding support for more languages, and improving support for existing ones are Adding support for more languages, and improving support for existing ones are
great places where you can contribute with a PR. great places where you can contribute with a PR.

View file

@ -170,7 +170,7 @@ The changes are, in no particular order:
- Add [ocaml-lsp] support - Add [ocaml-lsp] support
- Fix `Emac` typo - Fix misspelled "Emacs"
- Add [new-file-template.nvim] to automatically fill new file contents using - Add [new-file-template.nvim] to automatically fill new file contents using
templates templates

View file

@ -28,6 +28,10 @@
align with the "hunks" themed mapping and avoid conflict with the new [neogit] align with the "hunks" themed mapping and avoid conflict with the new [neogit]
group. group.
- LSP keybinds and related plugin integrations are now attached in an LspAttach
autocmd event. If you were calling `default_on_attach()` in your LSP setup you
can remove them now.
[NotAShelf](https://github.com/notashelf): [NotAShelf](https://github.com/notashelf):
[typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim [typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim
@ -68,7 +72,6 @@
- Add [](#opt-vim.lsp.lightbulb.autocmd.enable) for manually managing the - Add [](#opt-vim.lsp.lightbulb.autocmd.enable) for manually managing the
previously managed lightbulb autocommand. previously managed lightbulb autocommand.
- A warning will occur if [](#opt-vim.lsp.lightbulb.autocmd.enable) and - 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. `vim.lsp.lightbulb.setupOpts.autocmd.enabled` are both set at the same time.
Pick only one. Pick only one.
@ -111,6 +114,14 @@
- Add [hunk.nvim], Neovim plugin & tool for splitting diffs in Neovim. Available - Add [hunk.nvim], Neovim plugin & tool for splitting diffs in Neovim. Available
as `vim.git.hunk-nvim` as `vim.git.hunk-nvim`
- Move `crates.nvim` into `languages.rust.extensions and support` `setupOpts`
for the plugin. Deprecates the top level "crates" option in `languages.rust`.
[sjcobb2022](https://github.com/sjcobb2022):
- Migrate all current lsp configurations to `vim.lsp.server` and remove internal
dependency on `nvim-lspconfig`
[amadaluzia](https://github.com/amadaluzia): [amadaluzia](https://github.com/amadaluzia):
[haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim [haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim
@ -130,6 +141,11 @@
- Moved code setting `additionalRuntimePaths` and `enableLuaLoader` out of - Moved code setting `additionalRuntimePaths` and `enableLuaLoader` out of
`luaConfigPre`'s default to prevent being overridden `luaConfigPre`'s default to prevent being overridden
- Use conform over custom autocmds for LSP format on save - Use conform over custom autocmds for LSP format on save
- Move LSP keybinds and other related plugin integrations into an LspAttach
event.
- Allow multiple formatters in language modules.
- Fixed `prettier` in astro and svelte, and removed `prettierd` due to high
complexity that would be needed to support it.
[diniamo](https://github.com/diniamo): [diniamo](https://github.com/diniamo):
@ -284,6 +300,13 @@
- Fix [blink.cmp] breaking when built-in sources were modified. - Fix [blink.cmp] breaking when built-in sources were modified.
- Fix [conform.nvim] not allowing disabling formatting on and after save. Use - Fix [conform.nvim] not allowing disabling formatting on and after save. Use
`null` value to disable them if conform is enabled. `null` value to disable them if conform is enabled.
- Add [markdown-oxide](https://github.com/Feel-ix-343/markdown-oxide) option to
markdown language module.
- Fix Helm-YAML language module integration. YAML diagnostics will now remain in
`helmfile`s when both are enabled.
- Fix YAML language module not activating LSP keybinds if the Helm language
module was also enabled.
- Fix `json` language module (default) language server not activating.
[TheColorman](https://github.com/TheColorman): [TheColorman](https://github.com/TheColorman):
@ -319,6 +342,7 @@
- Add global function `nvf_lint` under - Add global function `nvf_lint` under
`vim.diagnostics.nvim-lint.lint_function`. `vim.diagnostics.nvim-lint.lint_function`.
- Deprecate `vim.scrollOffset` in favor of `vim.options.scrolloff`. - Deprecate `vim.scrollOffset` in favor of `vim.options.scrolloff`.
- Fix `svelte-language-server` not reloading .js/.ts files on change.
[Sc3l3t0n](https://github.com/Sc3l3t0n): [Sc3l3t0n](https://github.com/Sc3l3t0n):
@ -389,9 +413,12 @@
[poz](https://poz.pet): [poz](https://poz.pet):
[everforest]: https://github.com/sainnhe/everforest [everforest]: https://github.com/sainnhe/everforest
[oil]: https://github.com/stevearc/oil.nvim
[oil-git-status]: https://github.com/refractalize/oil-git-status.nvim
- Fix gitsigns null-ls issue. - Fix gitsigns null-ls issue.
- Add [everforest] theme support. - Add [everforest] theme support.
- Add [oil-git-status] support to [oil] module.
[Haskex](https://github.com/haskex): [Haskex](https://github.com/haskex):
@ -479,13 +506,8 @@
- fix broken `neorg` grammars - fix broken `neorg` grammars
- remove obsolete warning in the `otter` module - remove obsolete warning in the `otter` module
- add mainProgram attribute to vala language server wrapper
[Cool-Game-Dev](https://github.com/Cool-Game-Dev): - fix `crates-nvim`'s completions by using the in-program lsp
[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): [JManch](https://github.com/JManch):
@ -493,6 +515,56 @@
`autocomplete.nvim-cmp.enable` was disabled and `autocomplete.nvim-cmp.enable` was disabled and
`autocomplete.nvim-cmp.sources` had not been modified. `autocomplete.nvim-cmp.sources` had not been modified.
[Poseidon](https://github.com/poseidon-rises):
[nvim-biscuits]: https://github.com/code-biscuits/nvim-biscuits
[just-lsp]: https://github.com/terror/just-lsp
[roslyn-ls]: https://github.com/dotnet/vscode-csharp
[jsonls]: https://github.com/microsoft/vscode/tree/1.101.2/extensions/json-language-features/server
[jsonfmt]: https://github.com/caarlos0/jsonfmt
[superhtml]: https://github.com/kristoff-it/superhtml
[htmlHINT]: https://github.com/htmlhint/HTMLHint
[qmk-nvim]: https://github.com/codethread/qmk.nvim
[qmlls]: https://doc.qt.io/qt-6/qtqml-tooling-qmlls.html
[qmlformat]: https://doc.qt.io/qt-6/qtqml-tooling-qmlformat.html
- Add [nvim-biscuits] support under `vim.utility.nvim-biscuits`.
- Add just support under `vim.languages.just` using [just-lsp].
- Add [roslyn-ls] to the `vim.languages.csharp` module.
- Add JSON support under `vim.languages.json` using [jsonls] and [jsonfmt].
- Add advanced HTML support under `vim.languages.html` using [superhtml] and
[htmlHINT].
- Add QMK support under `vim.utility.qmk-nvim` via [qmk-nvim].
- Add QML support under `vim.languages.qml` using [qmlls] and [qmlformat].
[Morsicus](https://github.com/Morsicus):
- Add [EEx Treesitter Grammar](https://github.com/connorlay/tree-sitter-eex) for
Elixir
- Add
[HEEx Treesitter Grammar](https://github.com/phoenixframework/tree-sitter-heex)
for Elixir
[diced](https://github.com/diced):
- Fixed `typescript` treesitter grammar not being included by default.
[valterschutz](https://github.com/valterschutz):
[ruff]: (https://github.com/astral-sh/ruff)
- Add [ruff-fix] as a formatter option in `vim.languages.python.format.type`.
[gmvar](https://github.com/gmvar):
[harper-ls]: https://github.com/Automattic/harper
- Add [harper-ls] to the `vim.lsp` module.
[derethil](https://github.com/derethil):
- Fix `vim.lazy.plugins.<name>.enabled` Lua evaluation.
[Jules](https://github.com/jules-sommer): [Jules](https://github.com/jules-sommer):
[nvim-highlight-colors]: https://github.com/brenoprata10/nvim-highlight-colors [nvim-highlight-colors]: https://github.com/brenoprata10/nvim-highlight-colors
@ -517,3 +589,21 @@
[smoka7/hop.nvim]: https://github.com/smoka7/hop.nvim [smoka7/hop.nvim]: https://github.com/smoka7/hop.nvim
- Migrate [phaazon/hop.nvim] to [smoka7/hop.nvim] - Migrate [phaazon/hop.nvim] to [smoka7/hop.nvim]
[typst-concealer]. [simon-wg](https://github.com/simon-wg):
- Update `python` language module to use correct lsp binary.
- Fix `python` pyright and basedpyright language servers not using default on
attach behavior.
[critical](https://github.com/critical):
[mellow.nvim]: https://github.com/mellow-theme/mellow.nvim
- Add [mellow.nvim] plugin for vim and lualine theme support
[valyntyler](https://github.com/valyntyler):
[emmet-ls]: https://github.com/aca/emmet-ls
- Enable `languages.ts.format` for `.js` files
- Add [emmet-ls] to `html.lsp.servers`

6
flake.lock generated
View file

@ -53,11 +53,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1761880412, "lastModified": 1764081664,
"narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=", "narHash": "sha256-sUoHmPr/EwXzRMpv1u/kH+dXuvJEyyF2Q7muE+t0EU4=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386", "rev": "dc205f7b4fdb04c8b7877b43edb7b73be7730081",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -3,7 +3,6 @@
pkgs, pkgs,
config, config,
self', self',
inputs',
... ...
}: { }: {
devShells = { devShells = {

View file

@ -0,0 +1,48 @@
{
stdenv,
fetchFromGitHub,
nodejs,
pnpm_9,
pins,
}: let
pin = pins.prettier-plugin-astro;
in
stdenv.mkDerivation (finalAttrs: {
pname = "prettier-plugin-astro";
version = pin.version or pin.revision;
src = fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = finalAttrs.version;
sha256 = pin.hash;
};
pnpmDeps = pnpm_9.fetchDeps {
inherit (finalAttrs) pname src;
fetcherVersion = 2;
hash = "sha256-K7pIWLkIIbUKDIcysfEtcf/eVMX9ZgyFHdqcuycHCNE=";
};
nativeBuildInputs = [
nodejs
pnpm_9.configHook
];
buildPhase = ''
runHook preBuild
pnpm run build
runHook postBuild
'';
installPhase = ''
runHook preInstall
# mkdir -p $out/dist
cp -r dist/ $out
cp -r node_modules $out
runHook postInstall
'';
})

View file

@ -0,0 +1,19 @@
{
buildNpmPackage,
fetchFromGitHub,
pins,
}: let
pin = pins.prettier-plugin-svelte;
in
buildNpmPackage (finalAttrs: {
pname = "prettier-plugin-svelte";
version = pin.version or pin.revision;
src = fetchFromGitHub {
inherit (pin.repository) owner repo;
rev = finalAttrs.version;
sha256 = pin.hash;
};
npmDepsHash = "sha256-D+gDdKiIG38jV+M/BqTKf0yYj1KXpbIodtQFdzocpn8=";
})

View file

@ -8,7 +8,7 @@
# - the addition of the function `entryBefore` indicating a "wanted # - the addition of the function `entryBefore` indicating a "wanted
# by" relationship. # by" relationship.
{lib}: let {lib}: let
inherit (builtins) isAttrs attrValues attrNames elem all head tail length toJSON isString; inherit (builtins) isAttrs attrValues attrNames elem all head tail length toJSON isString removeAttrs;
inherit (lib.attrsets) filterAttrs mapAttrs; inherit (lib.attrsets) filterAttrs mapAttrs;
inherit (lib.lists) toposort; inherit (lib.lists) toposort;
inherit (lib.nvim.dag) empty isEntry entryBetween entryAfter entriesBetween entryAnywhere topoSort; inherit (lib.nvim.dag) empty isEntry entryBetween entryAfter entriesBetween entryAnywhere topoSort;
@ -169,10 +169,11 @@ in {
else value) else value)
dag; dag;
sortedDag = topoSort finalDag; sortedDag = topoSort finalDag;
loopDetail = map (loops: removeAttrs loops ["data"]) sortedDag.loops;
result = result =
if sortedDag ? result if sortedDag ? result
then mapResult sortedDag.result then mapResult sortedDag.result
else abort ("Dependency cycle in ${name}: " + toJSON sortedDag); else abort ("Dependency cycle in ${name}: " + toJSON loopDetail);
in in
result; result;
} }

View file

@ -1,7 +1,7 @@
{lib}: let {lib}: let
inherit (builtins) isString getAttr; inherit (builtins) isString getAttr;
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr; inherit (lib.types) listOf bool str submodule attrsOf anything either nullOr uniq;
inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) luaInline; inherit (lib.nvim.types) luaInline;
in { in {
@ -46,7 +46,7 @@ in {
capabilities = mkOption { capabilities = mkOption {
type = nullOr (either luaInline (attrsOf anything)); type = nullOr (either luaInline (attrsOf anything));
default = null; default = null;
description = "LSP capabilitiess to pass to lspconfig"; description = "LSP capabilities to pass to LSP server configuration";
}; };
on_attach = mkOption { on_attach = mkOption {
@ -58,11 +58,11 @@ in {
filetypes = mkOption { filetypes = mkOption {
type = nullOr (listOf str); type = nullOr (listOf str);
default = null; default = null;
description = "Filetypes to auto-attach LSP in"; description = "Filetypes to auto-attach LSP server in";
}; };
cmd = mkOption { cmd = mkOption {
type = nullOr (listOf str); type = nullOr (either luaInline (uniq (listOf str)));
default = null; default = null;
description = "Command used to start the LSP server"; description = "Command used to start the LSP server";
}; };

View file

@ -1,92 +1,52 @@
# Helpers for converting values to lua # Helpers for converting values to lua
{lib}: let {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;
inherit (lib.trivial) boolToString warn;
in rec {
# Convert a null value to lua's nil
nullString = value:
if value == null
then "nil"
else "'${value}'";
# convert an expression to lua
expToLua = exp:
if isList exp
then listToLuaTable exp # if list, convert to lua table
else if isAttrs exp
then attrsetToLuaTable exp # if attrs, convert to table
else if isBool exp
then boolToString exp # if bool, convert to string
else if isInt exp
then toString exp # if int, convert to string
else if exp == null
then "nil"
else (toJSON exp); # otherwise jsonify the value and print as is
# convert list to a lua table
listToLuaTable = list:
"{ " + (concatStringsSep ", " (map expToLua list)) + " }";
# convert attrset to a lua table
attrsetToLuaTable = attrset:
"{ "
+ (
concatStringsSep ", "
(
mapAttrsToList (
name: value:
name
+ " = "
+ (expToLua value)
)
attrset
)
)
+ " }";
# Convert a list of lua expressions to a lua table. The difference to listToLuaTable is that the elements here are expected to be lua expressions already, whereas listToLuaTable converts from nix types to lua first
luaTable = items: ''{${concatStringsSep "," items}}'';
isLuaInline = object: (object._type or null) == "lua-inline"; isLuaInline = object: (object._type or null) == "lua-inline";
toLuaObject = args: toLuaObject = args:
if isAttrs args {
then int = toString args;
if isLuaInline args float = toString args;
then args.expr
else if hasAttr "__empty" args # escapes \ and quotes
then string = builtins.toJSON args;
warn '' path = builtins.toJSON args;
Using `__empty` to define an empty lua table is deprecated. Use an empty attrset instead.
'' "{ }" bool = lib.boolToString args;
else null = "nil";
"{"
+ (concatStringsSep "," list = "{${lib.concatMapStringsSep ",\n" toLuaObject args}}";
(mapAttrsToList
(n: v: set =
if head (stringToCharacters n) == "@" if lib.isDerivation args
then toLuaObject v then ''"${args}"''
else "[${toLuaObject n}] = " + (toLuaObject v)) else if isLuaInline args
(filterAttrs then args.expr
(_: v: v != null) else "{${
args))) lib.pipe args [
+ "}" (lib.filterAttrs (_: v: v != null))
else if isList args (builtins.mapAttrs (
then "{" + concatMapStringsSep "," toLuaObject args + "}" n: v:
else if isString args if lib.hasPrefix "@" n
then then toLuaObject v
# This should be enough! else "[${toLuaObject n}] = ${toLuaObject v}"
toJSON args ))
else if isPath args builtins.attrValues
then toJSON (toString args) (lib.concatStringsSep ",\n")
else if isBool args ]
then "${boolToString args}" }}";
else if isFloat args }
then "${toString args}" .${
else if isInt args builtins.typeOf args
then "${toString args}" }
else if (args == null) or (builtins.throw "Could not convert object of type `${builtins.typeOf args}` to lua object");
then "nil" in
else throw "could not convert object of type `${typeOf args}` to lua object"; {
} inherit isLuaInline toLuaObject;
luaTable = x: (toLuaObject (map lib.mkLuaInline x));
}
// lib.genAttrs [
"nullString"
"expToLua"
"listToLuaTable"
"attrsetToLuaTable"
] (name: lib.warn "${name} is deprecated use toLuaObject instead" toLuaObject)

View file

@ -1,7 +1,10 @@
{lib}: let {lib}: let
inherit (builtins) toJSON;
inherit (lib.options) mergeEqualOption; inherit (lib.options) mergeEqualOption;
inherit (lib.lists) singleton;
inherit (lib.strings) isString stringLength match; inherit (lib.strings) isString stringLength match;
inherit (lib.types) listOf mkOptionType; inherit (lib.types) listOf mkOptionType coercedTo;
inherit (lib.trivial) warn;
in { in {
mergelessListOf = elemType: mergelessListOf = elemType:
mkOptionType { mkOptionType {
@ -25,4 +28,15 @@ in {
description = "RGB color in hex format"; description = "RGB color in hex format";
check = v: isString v && (match "#?[0-9a-fA-F]{6}" v) != null; check = v: isString v && (match "#?[0-9a-fA-F]{6}" v) != null;
}; };
# no compound types please
deprecatedSingleOrListOf = option: t:
coercedTo
t
(x:
warn ''
${option} no longer accepts non-list values, use [${toJSON x}] instead
''
(singleton x))
(listOf t);
} }

View file

@ -10,5 +10,5 @@ in {
inherit (typesDag) dagOf; inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType; inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType;
inherit (typesLanguage) diagnostics mkGrammarOption; inherit (typesLanguage) diagnostics mkGrammarOption;
inherit (customTypes) char hexColor mergelessListOf; inherit (customTypes) char hexColor mergelessListOf deprecatedSingleOrListOf;
} }

View file

@ -1,7 +1,9 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule; inherit (builtins) head;
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule doRename;
inherit (lib.lists) concatLists; inherit (lib.lists) concatLists;
inherit (lib.nvim.config) batchRenameOptions; inherit (lib.nvim.config) batchRenameOptions;
inherit (lib.trivial) warn;
renamedVimOpts = batchRenameOptions ["vim"] ["vim" "options"] { renamedVimOpts = batchRenameOptions ["vim"] ["vim" "options"] {
# 2024-12-01 # 2024-12-01
@ -20,6 +22,31 @@
# 2025-02-07 # 2025-02-07
scrollOffset = "scrolloff"; scrollOffset = "scrolloff";
}; };
mkRemovedLspOpt = lang: (mkRemovedOptionModule ["vim" "languages" lang "lsp" "opts"] ''
`vim.languages.${lang}.lsp.opts` is now moved to `vim.lsp.servers.<server_name>.init_options`
'');
mkRemovedLspPackage = lang: (mkRemovedOptionModule ["vim" "languages" lang "lsp" "package"] ''
`vim.languages.${lang}.lsp.package` is now moved to `vim.lsp.servers.<server_name>.cmd`
'');
mkRenamedLspServer = lang:
doRename
{
from = ["vim" "languages" lang "lsp" "server"];
to = ["vim" "languages" lang "lsp" "servers"];
visible = false;
warn = true;
use = x:
warn
"Obsolete option `vim.languages.${lang}.lsp.server` used, use `vim.languages.${lang}.lsp.servers` instead."
(head x);
};
mkRemovedFormatPackage = lang: (mkRemovedOptionModule ["vim" "languages" lang "format" "package"] ''
`vim.languages.${lang}.format.package` is removed, please use `vim.formatter.conform-nvim.formatters.<formatter_name>.command` instead.
'');
in { in {
imports = concatLists [ imports = concatLists [
[ [
@ -120,8 +147,165 @@ in {
in 'vim.clipboard.registers'. Please see the documentation for the new module for more in 'vim.clipboard.registers'. Please see the documentation for the new module for more
details, or open an issue if you are confused. details, or open an issue if you are confused.
'') '')
# 2025-07-12
(mkRenamedLspServer "assembly")
(mkRenamedLspServer "astro")
(mkRemovedLspPackage "astro")
(mkRenamedLspServer "bash")
(mkRemovedLspPackage "bash")
(mkRemovedLspOpt "clang")
(mkRemovedLspPackage "clang")
(mkRenamedLspServer "clang")
(mkRemovedLspPackage "clojure")
(mkRenamedLspServer "csharp")
(mkRemovedLspPackage "csharp")
(mkRenamedLspServer "css")
(mkRemovedLspPackage "css")
(mkRemovedLspPackage "cue")
(mkRenamedLspServer "dart")
(mkRemovedLspPackage "dart")
(mkRemovedLspOpt "dart")
(mkRenamedLspServer "elixir")
(mkRemovedLspPackage "elixir")
(mkRenamedLspServer "fsharp")
(mkRemovedLspPackage "fsharp")
(mkRenamedLspServer "gleam")
(mkRemovedLspPackage "gleam")
(mkRenamedLspServer "go")
(mkRemovedLspPackage "go")
(mkRemovedLspPackage "haskell")
(mkRemovedLspPackage "hcl")
(mkRenamedLspServer "helm")
(mkRemovedLspPackage "helm")
(mkRemovedLspPackage "java")
(mkRenamedLspServer "julia")
(mkRemovedLspPackage "julia")
(mkRemovedLspPackage "kotlin")
(mkRemovedLspPackage "lua")
(mkRenamedLspServer "markdown")
(mkRemovedLspPackage "markdown")
(mkRenamedLspServer "nim")
(mkRemovedLspPackage "nim")
(mkRenamedLspServer "nix")
(mkRemovedLspPackage "nix")
(mkRemovedOptionModule ["vim" "languages" "nix" "lsp" "options"] ''
`vim.languages.nix.lsp.options` has been moved to `vim.lsp.servers.<server_name>.init_options`.
'')
(mkRenamedLspServer "nu")
(mkRemovedLspPackage "nu")
(mkRenamedLspServer "ocaml")
(mkRemovedLspPackage "ocaml")
(mkRenamedLspServer "odin")
(mkRemovedLspPackage "odin")
(mkRenamedLspServer "php")
(mkRemovedLspPackage "php")
(mkRenamedLspServer "python")
(mkRemovedLspPackage "python")
(mkRenamedLspServer "r")
(mkRemovedLspPackage "r")
(mkRenamedLspServer "ruby")
(mkRemovedLspPackage "ruby")
(mkRenamedLspServer "sql")
(mkRemovedLspPackage "sql")
(mkRenamedLspServer "svelte")
(mkRemovedLspPackage "svelte")
(mkRenamedLspServer "tailwind")
(mkRemovedLspPackage "tailwind")
(mkRemovedLspPackage "terraform")
(mkRenamedLspServer "ts")
(mkRemovedLspPackage "ts")
(mkRenamedLspServer "typst")
(mkRemovedLspPackage "typst")
(mkRenamedLspServer "vala")
(mkRemovedLspPackage "vala")
(mkRenamedLspServer "wgsl")
(mkRemovedLspPackage "wgsl")
(mkRenamedLspServer "yaml")
(mkRemovedLspPackage "yaml")
(mkRenamedLspServer "zig")
(mkRemovedLspPackage "zig")
# 2025-10-22
(mkRenamedOptionModule ["vim" "languages" "rust" "crates" "enable"] ["vim" "languages" "rust" "extensions" "crates-nvim" "enable"])
(mkRemovedOptionModule ["vim" "languages" "rust" "crates" "codeActions"] ''
'vim.languages.rust.crates' option has been moved to 'vim.languages.rust.extensions.crates-nvim' in full and the
codeActions option has been removed. To set up code actions again, you may use the the new 'setupOpts' option
located under 'vim.languages.rust.extensions.crates-nvim'. Refer to crates.nvim documentation for setup steps:
<https://github.com/Saecki/crates.nvim/wiki/Documentation-v0.7.1#in-process-language-server>
'')
(mkRemovedOptionModule ["vim" "language" "astro" "format"] ''
This option has been removed due to being broken for a long time.
'')
(mkRemovedOptionModule ["vim" "language" "svelte" "format"] ''
This option has been removed due to being broken for a long time.
'')
] ]
(map mkRemovedFormatPackage [
"bash"
"css"
"elixir"
"fsharp"
"go"
"hcl"
"html"
"json"
"lua"
"markdown"
"nim"
"nix"
"ocaml"
"python"
"qml"
"r"
"ruby"
"rust"
"sql"
"ts"
"typst"
])
# Migrated via batchRenameOptions. Further batch renames must be below this line. # Migrated via batchRenameOptions. Further batch renames must be below this line.
renamedVimOpts renamedVimOpts
]; ];

View file

@ -9,7 +9,7 @@
inherit (lib.types) nullOr submodule listOf str bool; inherit (lib.types) nullOr submodule listOf str bool;
inherit (lib.nvim.types) luaInline; inherit (lib.nvim.types) luaInline;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter entryBetween;
autocommandType = submodule { autocommandType = submodule {
options = { options = {
@ -144,7 +144,7 @@ in {
enabledAutogroups = filter (au: au.enable) cfg.augroups; enabledAutogroups = filter (au: au.enable) cfg.augroups;
in { in {
luaConfigRC = { luaConfigRC = {
augroups = entryAfter ["pluginConfigs"] (optionalString (enabledAutogroups != []) '' augroups = entryBetween ["autocmds"] ["pluginConfigs"] (optionalString (enabledAutogroups != []) ''
local nvf_autogroups = {} local nvf_autogroups = {}
for _, group in ipairs(${toLuaObject enabledAutogroups}) do for _, group in ipairs(${toLuaObject enabledAutogroups}) do
if group.name then if group.name then

View file

@ -8,5 +8,6 @@
./highlight.nix ./highlight.nix
./lsp.nix ./lsp.nix
./spellcheck.nix ./spellcheck.nix
./util.nix
]; ];
} }

View file

@ -16,6 +16,7 @@
cfg = config.vim.lsp; cfg = config.vim.lsp;
# TODO: lspConfigurations filter on enabledServers instead of cfg.servers?
lspConfigurations = lspConfigurations =
mapAttrsToList ( mapAttrsToList (
name: value: '' name: value: ''
@ -76,7 +77,6 @@ in {
{ {
vim.lsp.servers."*" = { vim.lsp.servers."*" = {
capabilities = mkDefault (mkLuaInline "capabilities"); capabilities = mkDefault (mkLuaInline "capabilities");
on_attach = mkDefault (mkLuaInline "default_on_attach");
}; };
} }

View file

@ -9,7 +9,7 @@
inherit (lib.strings) concatLines concatStringsSep optionalString; inherit (lib.strings) concatLines concatStringsSep optionalString;
inherit (lib.attrsets) mapAttrsToList; inherit (lib.attrsets) mapAttrsToList;
inherit (lib.types) listOf str attrsOf; inherit (lib.types) listOf str attrsOf;
inherit (lib.nvim.lua) listToLuaTable; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
cfg = config.vim.spellcheck; cfg = config.vim.spellcheck;
@ -152,7 +152,7 @@ in {
vim.api.nvim_create_augroup("nvf_autocmds", {clear = false}) vim.api.nvim_create_augroup("nvf_autocmds", {clear = false})
vim.api.nvim_create_autocmd({ "FileType" }, { vim.api.nvim_create_autocmd({ "FileType" }, {
group = "nvf_autocmds", group = "nvf_autocmds",
pattern = ${listToLuaTable cfg.ignoredFiletypes}, pattern = ${toLuaObject cfg.ignoredFiletypes},
callback = function() callback = function()
vim.opt_local.spell = false vim.opt_local.spell = false
end, end,

View file

@ -0,0 +1,177 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.dag) entryBefore;
cfg = config.vim.lsp;
in {
config = mkMerge [
(mkIf (cfg.servers != {}) {
vim.luaConfigRC.lsp-util =
entryBefore ["lsp-servers"]
/*
lua
*/
''
-- Port of nvim-lspconfig util
local util = { path = {} }
util.default_config = {
log_level = vim.lsp.protocol.MessageType.Warning,
message_level = vim.lsp.protocol.MessageType.Warning,
settings = vim.empty_dict(),
init_options = vim.empty_dict(),
handlers = {},
autostart = true,
capabilities = vim.lsp.protocol.make_client_capabilities(),
}
-- global on_setup hook
util.on_setup = nil
do
local validate = vim.validate
local api = vim.api
local lsp = vim.lsp
local nvim_eleven = vim.fn.has 'nvim-0.11' == 1
local iswin = vim.uv.os_uname().version:match 'Windows'
local function escape_wildcards(path)
return path:gsub('([%[%]%?%*])', '\\%1')
end
local function is_fs_root(path)
if iswin then
return path:match '^%a:$'
else
return path == '/'
end
end
local function traverse_parents(path, cb)
path = vim.uv.fs_realpath(path)
local dir = path
-- Just in case our algo is buggy, don't infinite loop.
for _ = 1, 100 do
dir = vim.fs.dirname(dir)
if not dir then
return
end
-- If we can't ascend further, then stop looking.
if cb(dir, path) then
return dir, path
end
if is_fs_root(dir) then
break
end
end
end
util.root_pattern = function(...)
local patterns = util.tbl_flatten { ... }
return function(startpath)
startpath = util.strip_archive_subpath(startpath)
for _, pattern in ipairs(patterns) do
local match = util.search_ancestors(startpath, function(path)
for _, p in ipairs(vim.fn.glob(table.concat({ escape_wildcards(path), pattern }, '/'), true, true)) do
if vim.uv.fs_stat(p) then
return path
end
end
end)
if match ~= nil then
return match
end
end
end
end
util.root_markers_with_field = function(root_files, new_names, field, fname)
local path = vim.fn.fnamemodify(fname, ':h')
local found = vim.fs.find(new_names, { path = path, upward = true })
for _, f in ipairs(found or {}) do
-- Match the given `field`.
for line in io.lines(f) do
if line:find(field) then
root_files[#root_files + 1] = vim.fs.basename(f)
break
end
end
end
return root_files
end
util.insert_package_json = function(root_files, field, fname)
return util.root_markers_with_field(root_files, { 'package.json', 'package.json5' }, field, fname)
end
util.strip_archive_subpath = function(path)
-- Matches regex from zip.vim / tar.vim
path = vim.fn.substitute(path, 'zipfile://\\(.\\{-}\\)::[^\\\\].*$', '\\1', ''')
path = vim.fn.substitute(path, 'tarfile:\\(.\\{-}\\)::.*$', '\\1', ''')
return path
end
util.get_typescript_server_path = function(root_dir)
local project_roots = vim.fs.find('node_modules', { path = root_dir, upward = true, limit = math.huge })
for _, project_root in ipairs(project_roots) do
local typescript_path = project_root .. '/typescript'
local stat = vim.loop.fs_stat(typescript_path)
if stat and stat.type == 'directory' then
return typescript_path .. '/lib'
end
end
return '''
end
util.search_ancestors = function(startpath, func)
if nvim_eleven then
validate('func', func, 'function')
end
if func(startpath) then
return startpath
end
local guard = 100
for path in vim.fs.parents(startpath) do
-- Prevent infinite recursion if our algorithm breaks
guard = guard - 1
if guard == 0 then
return
end
if func(path) then
return path
end
end
end
util.path.is_descendant = function(root, path)
if not path then
return false
end
local function cb(dir, _)
return dir == root
end
local dir, _ = traverse_parents(path, cb)
return dir == root
end
util.tbl_flatten = function(t)
--- @diagnostic disable-next-line:deprecated
return nvim_eleven and vim.iter(t):flatten(math.huge):totable() or vim.tbl_flatten(t)
end
end
'';
})
];
}

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -10,8 +11,7 @@
cfg = config.vim.assistant.chatgpt; cfg = config.vim.assistant.chatgpt;
self = import ./chatgpt.nix {inherit lib;}; mappingDefinitions = options.vim.assistant.chatgpt.mappings;
mappingDefinitions = self.options.vim.assistant.chatgpt.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
maps = mkMerge [ maps = mkMerge [
(mkSetBinding mappings.editWithInstructions "<cmd>ChatGPTEditWithInstruction<CR>") (mkSetBinding mappings.editWithInstructions "<cmd>ChatGPTEditWithInstruction<CR>")

View file

@ -1,13 +1,58 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;
inherit (lib.options) mkOption mkEnableOption literalMD; inherit (lib.options) mkOption mkEnableOption literalMD;
inherit (lib.types) attrs either nullOr; inherit (lib.types) attrs either nullOr listOf submodule str;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.types) luaInline mkPluginSetupOption; inherit (lib.nvim.types) luaInline mkPluginSetupOption;
formattersType = submodule {
freeformType = attrs;
options = {
command = mkOption {
type = nullOr (either str luaInline);
default = null;
description = "The command to run.";
};
args = mkOption {
type = nullOr (either (listOf str) luaInline);
default = null;
description = ''
A list of strings, or a lua function that returns a list of strings.
Return a single string instead of a list to run the command in a
shell.
'';
};
prepend_args = mkOption {
type = nullOr (either (listOf str) luaInline);
default = null;
description = ''
When inherit = true, add additional arguments to the beginning of
args. Can also be a function, like args.
'';
};
append_args = mkOption {
type = nullOr (either (listOf str) luaInline);
default = null;
description = ''
When inherit = true, add additional arguments to the end of args.
Can also be a function, like args.
'';
};
};
};
in { in {
options.vim.formatter.conform-nvim = { options.vim.formatter.conform-nvim = {
enable = mkEnableOption "lightweight yet powerful formatter plugin for Neovim [conform-nvim]"; enable = mkEnableOption "lightweight yet powerful formatter plugin for Neovim [conform-nvim]";
setupOpts = mkPluginSetupOption "conform.nvim" { setupOpts = mkPluginSetupOption "conform.nvim" {
formatters = mkOption {
type = formattersType;
default = {};
description = "Custom formatters and overrides for built-in formatters.";
};
formatters_by_ft = mkOption { formatters_by_ft = mkOption {
type = attrs; type = attrs;
default = {}; default = {};

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -10,8 +11,7 @@
cfg = config.vim.git.git-conflict; cfg = config.vim.git.git-conflict;
self = import ./git-conflict.nix {inherit lib config;}; gcMappingDefinitions = options.vim.git.git-conflict.mappings;
gcMappingDefinitions = self.options.vim.git.git-conflict.mappings;
gcMappings = addDescriptionsToMappings cfg.mappings gcMappingDefinitions; gcMappings = addDescriptionsToMappings cfg.mappings gcMappingDefinitions;
in { in {

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (builtins) toJSON; inherit (builtins) toJSON;
@ -12,8 +13,7 @@
cfg = config.vim.git.gitsigns; cfg = config.vim.git.gitsigns;
self = import ./gitsigns.nix {inherit lib config;}; gsMappingDefinitions = options.vim.git.gitsigns.mappings;
gsMappingDefinitions = self.options.vim.git.gitsigns.mappings;
gsMappings = addDescriptionsToMappings cfg.mappings gsMappingDefinitions; gsMappings = addDescriptionsToMappings cfg.mappings gsMappingDefinitions;
in { in {

View file

@ -4,12 +4,24 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package; inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.meta) getExe;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.assembly; cfg = config.vim.languages.assembly;
defaultServers = ["asm-lsp"];
servers = {
asm-lsp = {
enable = true;
cmd = [(getExe pkgs.asm-lsp)];
filetypes = ["asm" "vmasm"];
root_markers = [".asm-lsp.toml" ".git"];
};
};
in { in {
options.vim.languages.assembly = { options.vim.languages.assembly = {
enable = mkEnableOption "Assembly support"; enable = mkEnableOption "Assembly support";
@ -20,12 +32,11 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Assembly LSP support (asm-lsp)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Assembly LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
package = mkOption { type = deprecatedSingleOrListOf "vim.language.asm.lsp.servers" (enum (attrNames servers));
type = package; default = defaultServers;
default = pkgs.asm-lsp; description = "Assembly LSP server to use";
description = "asm-lsp package";
}; };
}; };
}; };
@ -36,14 +47,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.asm-lsp = '' mapListToAttrs (n: {
lspconfig.asm_lsp.setup { name = n;
capabilities = capabilities, value = servers.${n};
on_attach = default_on_attach, })
cmd = {"${cfg.lsp.package}/bin/asm-lsp"}, cfg.lsp.servers;
}
'';
}) })
]); ]);
} }

View file

@ -1,4 +1,5 @@
{ {
self,
config, config,
pkgs, pkgs,
lib, lib,
@ -7,49 +8,54 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum coercedTo;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.types) mkGrammarOption diagnostics deprecatedSingleOrListOf;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.astro; cfg = config.vim.languages.astro;
defaultServer = "astro"; defaultServers = ["astro"];
servers = { servers = {
astro = { astro = {
package = pkgs.astro-language-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.astro-language-server) "--stdio"];
lspconfig.astro.setup { filetypes = ["astro"];
capabilities = capabilities, root_markers = ["package.json" "tsconfig.json" "jsconfig.json" ".git"];
on_attach = attach_keymaps, init_options = {
cmd = ${ typescript = {};
if isList cfg.lsp.package };
then expToLua cfg.lsp.package before_init =
else ''{"${cfg.lsp.package}/bin/astro-ls", "--stdio"}'' mkLuaInline
} /*
} lua
''; */
''
function(_, config)
if config.init_options and config.init_options.typescript and not config.init_options.typescript.tsdk then
config.init_options.typescript.tsdk = util.get_typescript_server_path(config.root_dir)
end
end
'';
}; };
}; };
# TODO: specify packages defaultFormat = ["prettier"];
defaultFormat = "prettier"; formats = let
formats = { parser = "${self.packages.${pkgs.stdenv.hostPlatform.system}.prettier-plugin-astro}/index.js";
in {
prettier = { prettier = {
package = pkgs.prettier; command = getExe pkgs.prettier;
}; options.ft_parsers.astro = "astro";
prepend_args = ["--plugin=${parser}"];
prettierd = {
package = pkgs.prettierd;
}; };
biome = { biome = {
package = pkgs.biome; command = getExe pkgs.biome;
}; };
}; };
# TODO: specify packages
defaultDiagnosticsProvider = ["eslint_d"]; defaultDiagnosticsProvider = ["eslint_d"];
diagnosticsProviders = { diagnosticsProviders = {
eslint_d = let eslint_d = let
@ -69,6 +75,15 @@
}; };
}; };
}; };
formatType =
deprecatedSingleOrListOf
"vim.languages.astro.format.type"
(coercedTo (enum ["prettierd"]) (_:
lib.warn
"vim.languages.astro.format.type: prettierd is deprecated, use prettier instead"
"prettier")
(enum (attrNames formats)));
in { in {
options.vim.languages.astro = { options.vim.languages.astro = {
enable = mkEnableOption "Astro language support"; enable = mkEnableOption "Astro language support";
@ -81,34 +96,20 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Astro LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Astro LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.astro.lsp.servers" (enum (attrNames servers));
type = enum (attrNames servers); default = defaultServers;
default = defaultServer;
description = "Astro LSP server to use"; description = "Astro LSP server to use";
}; };
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
example = ''[lib.getExe pkgs.astro-language-server "--minify" "--stdio"]'';
description = "Astro LSP server package, or the command to run as a list of strings";
};
}; };
format = { format = {
enable = mkEnableOption "Astro formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Astro formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Astro formatter to use"; type = formatType;
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Astro formatter to use";
package = mkOption {
description = "Astro formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -130,16 +131,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.astro-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.astro = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.astro = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -5,38 +5,35 @@
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum bool;
inherit (lib.types) enum either package listOf str bool; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) diagnostics mkGrammarOption; inherit (lib.nvim.types) diagnostics mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.bash; cfg = config.vim.languages.bash;
defaultServer = "bash-ls"; defaultServers = ["bash-ls"];
servers = { servers = {
bash-ls = { bash-ls = {
package = pkgs.bash-language-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.bash-language-server) "start"];
lspconfig.bashls.setup{ filetypes = ["bash" "sh"];
capabilities = capabilities; root_markers = [".git"];
on_attach = default_on_attach; settings = {
cmd = ${ basheIde = {
if isList cfg.lsp.package globPattern = mkLuaInline "vim.env.GLOB_PATTERN or '*@(.sh|.inc|.bash|.command)'";
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/bash-language-server", "start"}''
}; };
} };
'';
}; };
}; };
defaultFormat = "shfmt"; defaultFormat = ["shfmt"];
formats = { formats = {
shfmt = { shfmt = {
package = pkgs.shfmt; command = getExe pkgs.shfmt;
}; };
}; };
@ -56,38 +53,24 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Enable Bash LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Bash LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.bash.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Bash LSP server to use"; description = "Bash LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "bash-language-server package, or the command to run as a list of strings";
example = literalExpression ''[lib.getExe pkgs.bash-language-server "start"]'';
type = either package (listOf str);
default = pkgs.bash-language-server;
}; };
}; };
format = { format = {
enable = mkOption { enable = mkOption {
description = "Enable Bash formatting";
type = bool; type = bool;
default = config.vim.languages.enableFormat; default = config.vim.languages.enableFormat;
description = "Enable Bash formatting";
}; };
type = mkOption { type = mkOption {
description = "Bash formatter to use"; type = deprecatedSingleOrListOf "vim.language.bash.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Bash formatter to use";
package = mkOption {
description = "Bash formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -108,16 +91,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.bash-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.sh = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.sh = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -5,47 +5,139 @@
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.lists) isList;
inherit (lib.strings) optionalString;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) bool enum package either listOf str nullOr; inherit (lib.types) bool enum package;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.lua) expToLua; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
packageToCmd = package: defaultCmd:
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{ "${cfg.lsp.package}/bin/${defaultCmd}" }'';
cfg = config.vim.languages.clang; cfg = config.vim.languages.clang;
defaultServer = "clangd"; defaultServers = ["clangd"];
servers = { servers = {
ccls = { ccls = {
package = pkgs.ccls; cmd = [(getExe pkgs.ccls)];
lspConfig = '' filetypes = ["c" "cpp" "objc" "objcpp" "cuda"];
lspconfig.ccls.setup{ offset_encoding = "utf-32";
capabilities = capabilities; root_markers = ["compile_commands.json" ".ccls" ".git"];
on_attach=default_on_attach; workspace_required = true;
cmd = ${packageToCmd cfg.lsp.package "ccls"}; on_attach = mkLuaInline ''
${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.opts}"} function(client, bufnr)
} local function switch_source_header(bufnr)
local method_name = "textDocument/switchSourceHeader"
local params = vim.lsp.util.make_text_document_params(bufnr)
client:request(method_name, params, function(err, result)
if err then
error(tostring(err))
end
if not result then
vim.notify('corresponding file cannot be determined')
return
end
vim.cmd.edit(vim.uri_to_fname(result))
end, bufnr)
end
vim.api.nvim_buf_create_user_command(
bufnr,
"LspCclsSwitchSourceHeader",
function(arg)
switch_source_header(client, 0)
end,
{desc = "Switch between source/header"}
)
end
''; '';
}; };
clangd = { clangd = {
package = pkgs.clang-tools; cmd = ["${pkgs.clang-tools}/bin/clangd"];
lspConfig = '' filetypes = ["c" "cpp" "objc" "objcpp" "cuda" "proto"];
local clangd_cap = capabilities root_markers = [
-- use same offsetEncoding as null-ls ".clangd"
clangd_cap.offsetEncoding = {"utf-16"} ".clang-tidy"
lspconfig.clangd.setup{ ".clang-format"
capabilities = clangd_cap; "compile_commands.json"
on_attach=default_on_attach; "compile_flags.txt"
cmd = ${packageToCmd cfg.lsp.package "clangd"}; "configure.ac"
${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.opts}"} ".git"
} ];
capabilities = {
textDocument = {
completion = {
editsNearCursor = true;
};
};
offsetEncoding = ["utf-8" "utf-16"];
};
on_attach = mkLuaInline ''
function(client, bufnr)
local function switch_source_header(bufnr)
local method_name = "textDocument/switchSourceHeader"
local client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd", })[1]
if not client then
return vim.notify(('method %s is not supported by any servers active on the current buffer'):format(method_name))
end
local params = vim.lsp.util.make_text_document_params(bufnr)
client.request(method_name, params, function(err, result)
if err then
error(tostring(err))
end
if not result then
vim.notify('corresponding file cannot be determined')
return
end
vim.cmd.edit(vim.uri_to_fname(result))
end, bufnr)
end
local function symbol_info()
local bufnr = vim.api.nvim_get_current_buf()
local clangd_client = vim.lsp.get_clients({ bufnr = bufnr, name = "clangd" })[1]
if not clangd_client or not clangd_client.supports_method 'textDocument/symbolInfo' then
return vim.notify('Clangd client not found', vim.log.levels.ERROR)
end
local win = vim.api.nvim_get_current_win()
local params = vim.lsp.util.make_position_params(win, clangd_client.offset_encoding)
clangd_client:request('textDocument/symbolInfo', params, function(err, res)
if err or #res == 0 then
-- Clangd always returns an error, there is not reason to parse it
return
end
local container = string.format('container: %s', res[1].containerName) ---@type string
local name = string.format('name: %s', res[1].name) ---@type string
vim.lsp.util.open_floating_preview({ name, container }, "", {
height = 2,
width = math.max(string.len(name), string.len(container)),
focusable = false,
focus = false,
border = 'single',
title = 'Symbol Info',
})
end, bufnr)
end
vim.api.nvim_buf_create_user_command(
bufnr,
"ClangdSwitchSourceHeader",
function(arg)
switch_source_header(0)
end,
{desc = "Switch between source/header"}
)
vim.api.nvim_buf_create_user_command(
bufnr,
"ClangdShowSymbolInfo",
function(arg)
symbol_info()
end,
{desc = "Show symbol info"}
)
end
''; '';
}; };
}; };
@ -100,23 +192,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "clang LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "clang LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
description = "The clang LSP server to use"; description = "The clang LSP server to use";
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.clang.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
};
package = mkOption {
description = "clang LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
};
opts = mkOption {
description = "Options to pass to clang LSP server";
type = nullOr str;
default = null;
}; };
}; };
@ -150,9 +229,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
mapListToAttrs (name: {
vim.lsp.lspconfig.sources.clang-lsp = servers.${cfg.lsp.server}.lspConfig; inherit name;
value = servers.${name};
})
cfg.lsp.servers;
}) })
(mkIf cfg.dap.enable { (mkIf cfg.dap.enable {

View file

@ -4,15 +4,25 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.lists) isList; inherit (lib.types) enum listOf;
inherit (lib.types) either listOf package str;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.clojure; cfg = config.vim.languages.clojure;
defaultServers = ["clojure-lsp"];
servers = {
clojure-lsp = {
enable = true;
cmd = [(getExe pkgs.clojure-lsp)];
filetypes = ["clojure" "edn"];
root_markers = ["project.clj" "deps.edn" "build.boot" "shadow-cljs.edn" ".git" "bb.edn"];
};
};
in { in {
options.vim.languages.clojure = { options.vim.languages.clojure = {
enable = mkEnableOption "Clojure language support"; enable = mkEnableOption "Clojure language support";
@ -24,28 +34,22 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Clojure LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Clojure LSP support" // {default = config.vim.lsp.enable;};
package = mkOption { servers = mkOption {
type = either package (listOf str); type = listOf (enum (attrNames servers));
default = pkgs.clojure-lsp; default = defaultServers;
description = "Clojure LSP"; description = "Clojure LSP server to use";
}; };
}; };
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.clojure-lsp = '' mapListToAttrs (n: {
lspconfig.clojure_lsp.setup { name = n;
capabilities = capabilities; value = servers.${n};
on_attach = default_on_attach; })
cmd = ${ cfg.lsp.servers;
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${getExe cfg.lsp.package}"}''
};
}
'';
}) })
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {

View file

@ -5,14 +5,16 @@
options, options,
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames concatMap;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) either listOf package str enum; inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.generators) mkLuaInline;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.attrsets) mapListToAttrs;
lspKeyConfig = config.vim.lsp.mappings; lspKeyConfig = config.vim.lsp.mappings;
lspKeyOptions = options.vim.lsp.mappings; lspKeyOptions = options.vim.lsp.mappings;
@ -25,58 +27,147 @@
# Omnisharp doesn't have colors in popup docs for some reason, and I've also # Omnisharp doesn't have colors in popup docs for some reason, and I've also
# seen mentions of it being way slower, so until someone finds missing # seen mentions of it being way slower, so until someone finds missing
# functionality, this will be the default. # functionality, this will be the default.
defaultServer = "csharp_ls"; defaultServers = ["csharp_ls"];
servers = { servers = {
omnisharp = { omnisharp = {
package = pkgs.omnisharp-roslyn; cmd = mkLuaInline ''
internalFormatter = true; {
lspConfig = '' ${toLuaObject (getExe pkgs.omnisharp-roslyn)},
lspconfig.omnisharp.setup { '-z', -- https://github.com/OmniSharp/omnisharp-vscode/pull/4300
capabilities = capabilities, '--hostPID',
on_attach = function(client, bufnr) tostring(vim.fn.getpid()),
default_on_attach(client, bufnr) 'DotNet:enablePackageRestore=false',
'--encoding',
local oe = require("omnisharp_extended") 'utf-8',
${mkLspBinding "goToDefinition" "oe.lsp_definition"} '--languageserver',
${mkLspBinding "goToType" "oe.lsp_type_definition"}
${mkLspBinding "listReferences" "oe.lsp_references"}
${mkLspBinding "listImplementations" "oe.lsp_implementation"}
end,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else "{'${cfg.lsp.package}/bin/OmniSharp'}"
}
} }
''; '';
filetypes = ["cs" "vb"];
root_dir = mkLuaInline ''
function(bufnr, on_dir)
local function find_root_pattern(fname, lua_pattern)
return vim.fs.root(0, function(name, path)
return name:match(lua_pattern)
end)
end
local fname = vim.api.nvim_buf_get_name(bufnr)
on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
end
'';
init_options = {};
capabilities = {
workspace = {
workspaceFolders = false; # https://github.com/OmniSharp/omnisharp-roslyn/issues/909
};
};
on_attach = mkLuaInline ''
function(client, bufnr)
local oe = require("omnisharp_extended")
${mkLspBinding "goToDefinition" "oe.lsp_definition"}
${mkLspBinding "goToType" "oe.lsp_type_definition"}
${mkLspBinding "listReferences" "oe.lsp_references"}
${mkLspBinding "listImplementations" "oe.lsp_implementation"}
end
'';
settings = {
FormattingOptions = {
# Enables support for reading code style, naming convention and analyzer
# settings from .editorconfig.
EnableEditorConfigSupport = true;
# Specifies whether 'using' directives should be grouped and sorted during
# document formatting.
OrganizeImports = null;
};
MsBuild = {
# If true, MSBuild project system will only load projects for files that
# were opened in the editor. This setting is useful for big C# codebases
# and allows for faster initialization of code navigation features only
# for projects that are relevant to code that is being edited. With this
# setting enabled OmniSharp may load fewer projects and may thus display
# incomplete reference lists for symbols.
LoadProjectsOnDemand = null;
};
RoslynExtensionsOptions = {
# Enables support for roslyn analyzers, code fixes and rulesets.
EnableAnalyzersSupport = null;
# Enables support for showing unimported types and unimported extension
# methods in completion lists. When committed, the appropriate using
# directive will be added at the top of the current file. This option can
# have a negative impact on initial completion responsiveness;
# particularly for the first few completion sessions after opening a
# solution.
EnableImportCompletion = null;
# Only run analyzers against open files when 'enableRoslynAnalyzers' is
# true
AnalyzeOpenDocumentsOnly = null;
# Enables the possibility to see the code in external nuget dependencies
EnableDecompilationSupport = null;
};
RenameOptions = {
RenameInComments = null;
RenameOverloads = null;
RenameInStrings = null;
};
Sdk = {
# Specifies whether to include preview versions of the .NET SDK when
# determining which version to use for project loading.
IncludePrereleases = true;
};
};
}; };
csharp_ls = { csharp_ls = {
package = pkgs.csharp-ls; cmd = [(lib.getExe pkgs.csharp-ls)];
internalFormatter = true; filetypes = ["cs"];
lspConfig = '' root_dir = mkLuaInline ''
local extended_handler = require("csharpls_extended").handler function(bufnr, on_dir)
local function find_root_pattern(fname, lua_pattern)
return vim.fs.root(0, function(name, path)
return name:match(lua_pattern)
end)
end
lspconfig.csharp_ls.setup { local fname = vim.api.nvim_buf_get_name(bufnr)
capabilities = capabilities, on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
on_attach = default_on_attach, end
handlers = { '';
["textDocument/definition"] = extended_handler, init_options = {
["textDocument/typeDefinition"] = extended_handler AutomaticWorkspaceInit = true;
}, };
cmd = ${ };
if isList cfg.lsp.package
then expToLua cfg.lsp.package roslyn_ls = {
else "{'${cfg.lsp.package}/bin/csharp-ls'}" cmd = mkLuaInline ''
} {
${toLuaObject (getExe pkgs.roslyn-ls)},
'--logLevel=Warning',
'--extensionLogDirectory=' .. vim.fs.dirname(vim.lsp.get_log_path()),
'--stdio',
} }
''; '';
filetypes = ["cs"];
root_dir = mkLuaInline ''
function(bufnr, on_dir)
local function find_root_pattern(fname, lua_pattern)
return vim.fs.root(0, function(name, path)
return name:match(lua_pattern)
end)
end
local fname = vim.api.nvim_buf_get_name(bufnr)
on_dir(find_root_pattern(fname, "%.sln$") or find_root_pattern(fname, "%.csproj$"))
end
'';
init_options = {};
}; };
}; };
extraServerPlugins = { extraServerPlugins = {
omnisharp = ["omnisharp-extended-lsp-nvim"]; omnisharp = ["omnisharp-extended-lsp-nvim"];
csharp_ls = ["csharpls-extended-lsp-nvim"]; csharp_ls = ["csharpls-extended-lsp-nvim"];
roslyn_ls = [];
}; };
cfg = config.vim.languages.csharp; cfg = config.vim.languages.csharp;
@ -92,16 +183,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "C# LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "C# LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
description = "C# LSP server to use"; description = "C# LSP server to use";
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.csharp.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
};
package = mkOption {
description = "C# LSP server package, or the command to run as a list of strings";
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
}; };
@ -114,9 +199,13 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.startPlugins = extraServerPlugins.${cfg.lsp.server} or []; vim.startPlugins = concatMap (server: extraServerPlugins.${server}) cfg.lsp.servers;
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.csharp-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -8,65 +8,40 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) enum either listOf package str; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.lua) expToLua;
cfg = config.vim.languages.css; cfg = config.vim.languages.css;
defaultServer = "vscode-langservers-extracted"; defaultServer = ["cssls"];
servers = { servers = {
vscode-langservers-extracted = { cssls = {
package = pkgs.vscode-langservers-extracted; cmd = ["${pkgs.vscode-langservers-extracted}/bin/vscode-css-language-server" "--stdio"];
lspConfig = '' filetypes = ["css" "scss" "less"];
-- enable (broadcasting) snippet capability for completion # needed to enable formatting
-- see <https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#cssls> init_options = {provideFormatter = true;};
local css_capabilities = vim.lsp.protocol.make_client_capabilities() root_markers = [".git" "package.json"];
css_capabilities.textDocument.completion.completionItem.snippetSupport = true settings = {
css.validate = true;
-- cssls setup scss.validate = true;
lspconfig.cssls.setup { less.validate = true;
capabilities = css_capabilities; };
on_attach = default_on_attach;
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/vscode-css-language-server", "--stdio"}''
}
}
'';
}; };
}; };
defaultFormat = "prettier"; defaultFormat = ["prettier"];
formats = { formats = {
prettier = { prettier = {
package = pkgs.prettier; command = getExe pkgs.prettier;
}; };
prettierd = { prettierd = {
package = pkgs.prettierd; command = getExe pkgs.prettierd;
nullConfig = ''
table.insert(
ls_sources,
null_ls.builtins.formatting.prettier.with({
command = "${cfg.format.package}/bin/prettierd",
})
)
'';
}; };
biome = { biome = {
package = pkgs.biome; command = getExe pkgs.biome;
nullConfig = ''
table.insert(
ls_sources,
null_ls.builtins.formatting.biome.with({
command = "${cfg.format.package}/bin/biome",
})
)
'';
}; };
}; };
in { in {
@ -82,17 +57,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "CSS LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "CSS LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
description = "CSS LSP server to use"; type = deprecatedSingleOrListOf "vim.language.css.lsp.servers" (enum (attrNames servers));
type = enum (attrNames servers);
default = defaultServer; default = defaultServer;
}; description = "CSS LSP server to use";
package = mkOption {
description = "CSS LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -101,15 +69,9 @@ in {
type = mkOption { type = mkOption {
description = "CSS formatter to use"; description = "CSS formatter to use";
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.css.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
}; };
package = mkOption {
description = "CSS formatter package";
type = package;
default = formats.${cfg.format.type}.package;
};
}; };
}; };
@ -120,16 +82,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.css-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.css = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.css = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -4,11 +4,17 @@
lib, lib,
... ...
}: let }: let
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption;
inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
lspOptions = {
cmd = [(getExe pkgs.cue) "lsp"];
filetypes = ["cue"];
root_markers = ["cue.mod" ".git"];
};
cfg = config.vim.languages.cue; cfg = config.vim.languages.cue;
in { in {
options.vim.languages.cue = { options.vim.languages.cue = {
@ -22,12 +28,6 @@ in {
lsp = { lsp = {
enable = mkEnableOption "CUE LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "CUE LSP support" // {default = config.vim.lsp.enable;};
package = mkOption {
type = package;
default = pkgs.cue;
description = "cue lsp implementation";
};
}; };
}; };
@ -38,14 +38,7 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers.cue = lspOptions;
vim.lsp.lspconfig.sources.cue-lsp = ''
lspconfig.cue.setup {
capabilities = capabilities,
on_attach = default_on_attach,
cmd = {"${cfg.lsp.package}/bin/cue", "lsp"},
}
'';
}) })
]); ]);
} }

View file

@ -6,34 +6,38 @@
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.trivial) boolToString; inherit (lib.trivial) boolToString;
inherit (lib.lists) isList;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum either listOf package nullOr str bool; inherit (lib.types) enum package nullOr str bool;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.dart; cfg = config.vim.languages.dart;
ftcfg = cfg.flutter-tools; ftcfg = cfg.flutter-tools;
defaultServer = "dart"; defaultServers = ["dart"];
servers = { servers = {
dart = { dart = {
package = pkgs.dart; enable = true;
lspConfig = '' cmd = [(getExe pkgs.dart) "language-server" "--protocol=lsp"];
lspconfig.dartls.setup{ filetypes = ["dart"];
capabilities = capabilities; root_markers = ["pubspec.yaml"];
on_attach=default_on_attach; init_options = {
cmd = ${ onlyAnalyzeProjectsWithOpenFiles = true;
if isList cfg.lsp.package suggestFromUnimportedLibraries = true;
then expToLua cfg.lsp.package closingLabels = true;
else ''{"${cfg.lsp.package}/bin/dart", "language-server", "--protocol=lsp"}'' outline = true;
flutterOutline = true;
};
settings = {
dart = {
completeFunctionCalls = true;
showTodos = true;
}; };
${optionalString (cfg.lsp.opts != null) "init_options = ${cfg.lsp.dartOpts}"} };
}
'';
}; };
}; };
in { in {
@ -46,23 +50,11 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Dart LSP support"; enable = mkEnableOption "Dart LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
description = "The Dart LSP server to use"; type = deprecatedSingleOrListOf "vim.language.dart.lsp.servers" (enum (attrNames servers));
type = enum (attrNames servers); default = defaultServers;
default = defaultServer; description = "Dart LSP server to use";
};
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
description = "Dart LSP server package, or the command to run as a list of strings";
};
opts = mkOption {
type = nullOr str;
default = null;
description = "Options to pass to Dart LSP server";
}; };
}; };
@ -131,19 +123,23 @@ in {
}; };
}; };
config.vim = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {
treesitter.enable = true; vim.treesitter.enable = true;
treesitter.grammars = [cfg.treesitter.package]; vim.treesitter.grammars = [cfg.treesitter.package];
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
lsp.lspconfig.enable = true; vim.lsp.servers =
lsp.lspconfig.sources.dart-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf ftcfg.enable { (mkIf ftcfg.enable {
startPlugins = [ vim.startPlugins = [
( (
if ftcfg.enableNoResolvePatch if ftcfg.enableNoResolvePatch
then "flutter-tools-patched" then "flutter-tools-patched"
@ -152,7 +148,7 @@ in {
"plenary-nvim" "plenary-nvim"
]; ];
pluginRC.flutter-tools = entryAfter ["lsp-setup"] '' vim.pluginRC.flutter-tools = entryAfter ["lsp-servers"] ''
require('flutter-tools').setup { require('flutter-tools').setup {
${optionalString (ftcfg.flutterPackage != null) "flutter_path = \"${ftcfg.flutterPackage}/bin/flutter\","} ${optionalString (ftcfg.flutterPackage != null) "flutter_path = \"${ftcfg.flutterPackage}/bin/flutter\","}
lsp = { lsp = {
@ -165,7 +161,6 @@ in {
}, },
capabilities = capabilities, capabilities = capabilities,
on_attach = default_on_attach;
}, },
${optionalString cfg.dap.enable '' ${optionalString cfg.dap.enable ''
debugger = { debugger = {

View file

@ -21,6 +21,7 @@ in {
./html.nix ./html.nix
./haskell.nix ./haskell.nix
./java.nix ./java.nix
./json.nix
./lua.nix ./lua.nix
./markdown.nix ./markdown.nix
./nim.nix ./nim.nix
@ -29,6 +30,7 @@ in {
./ocaml.nix ./ocaml.nix
./php.nix ./php.nix
./python.nix ./python.nix
./qml.nix
./r.nix ./r.nix
./rust.nix ./rust.nix
./scala.nix ./scala.nix
@ -46,6 +48,7 @@ in {
./wgsl.nix ./wgsl.nix
./yaml.nix ./yaml.nix
./ruby.nix ./ruby.nix
./just.nix
# This is now a hard deprecation. # This is now a hard deprecation.
(mkRenamedOptionModule ["vim" "languages" "enableLSP"] ["vim" "lsp" "enable"]) (mkRenamedOptionModule ["vim" "languages" "enableLSP"] ["vim" "lsp" "enable"])

View file

@ -7,40 +7,43 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.elixir; cfg = config.vim.languages.elixir;
defaultServer = "elixirls"; defaultServers = ["elixirls"];
servers = { servers = {
elixirls = { elixirls = {
package = pkgs.elixir-ls; enable = true;
lspConfig = '' cmd = [(getExe pkgs.elixir-ls)];
-- elixirls setup filetypes = ["elixir" "eelixir" "heex" "surface"];
lspconfig.elixirls.setup { root_dir =
capabilities = capabilities, mkLuaInline
on_attach = default_on_attach, /*
cmd = ${ lua
if isList cfg.lsp.package */
then expToLua cfg.lsp.package ''
else ''{"${cfg.lsp.package}/bin/elixir-ls"}'' function(bufnr, on_dir)
} local fname = vim.api.nvim_buf_get_name(bufnr)
} local matches = vim.fs.find({ 'mix.exs' }, { upward = true, limit = 2, path = fname })
''; local child_or_root_path, maybe_umbrella_path = unpack(matches)
local root_dir = vim.fs.dirname(maybe_umbrella_path or child_or_root_path)
on_dir(root_dir)
end
'';
}; };
}; };
defaultFormat = "mix"; defaultFormat = ["mix"];
formats = { formats = {
mix = { mix = {
package = pkgs.elixir; command = "${pkgs.elixir}/bin/mix";
config = {
command = "${cfg.format.package}/bin/mix";
};
}; };
}; };
in { in {
@ -50,22 +53,16 @@ in {
treesitter = { treesitter = {
enable = mkEnableOption "Elixir treesitter" // {default = config.vim.languages.enableTreesitter;}; enable = mkEnableOption "Elixir treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "elixir"; package = mkGrammarOption pkgs "elixir";
heexPackage = mkGrammarOption pkgs "heex";
eexPackage = mkGrammarOption pkgs "eex";
}; };
lsp = { lsp = {
enable = mkEnableOption "Elixir LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Elixir LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.elixir.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Elixir LSP server to use"; description = "Elixir LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Elixir LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -73,15 +70,9 @@ in {
enable = mkEnableOption "Elixir formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Elixir formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Elixir formatter to use"; type = deprecatedSingleOrListOf "vim.language.elixir.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Elixir formatter to use";
package = mkOption {
description = "Elixir formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -93,20 +84,34 @@ in {
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {
vim.treesitter.enable = true; vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package]; vim.treesitter.grammars = [
cfg.treesitter.package
cfg.treesitter.heexPackage
cfg.treesitter.eexPackage
];
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.elixir-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.elixir = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = formatters_by_ft.elixir = cfg.format.type;
formats.${cfg.format.type}.config; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
}; };
}) })

View file

@ -6,36 +6,55 @@
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) either listOf package str enum; inherit (lib.types) enum;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
defaultServer = "fsautocomplete"; defaultServer = ["fsautocomplete"];
servers = { servers = {
fsautocomplete = { fsautocomplete = {
package = pkgs.fsautocomplete; cmd = [(getExe pkgs.fsautocomplete) "--adaptive-lsp-server-enabled"];
internalFormatter = false; filetypes = ["fsharp"];
lspConfig = '' root_dir = mkLuaInline ''
lspconfig.fsautocomplete.setup { function(bufnr, on_dir)
capabilities = capabilities; on_dir(vim.fs.root(bufnr, function(name, path)
on_attach = default_on_attach; return name == ".git" or name:match("%.sln$") or name:match("%.fsproj$")
cmd = ${ end))
if isList cfg.lsp.package end
then expToLua cfg.lsp.package
else "{'${cfg.lsp.package}/bin/fsautocomplete'}"
},
}
''; '';
init_options = {
AutomaticWorkspaceInit = true;
};
settings = {
FSharp = {
keywordsAutocomplete = true;
ExternalAutocomplete = false;
Linter = true;
UnionCaseStubGeneration = true;
UnionCaseStubGenerationBody = ''failwith "Not Implemented"'';
RecordStubGeneration = true;
RecordStubGenerationBody = ''failwith "Not Implemented"'';
InterfaceStubGeneration = true;
InterfaceStubGenerationObjectIdentifier = "this";
InterfaceStubGenerationMethodBody = ''failwith "Not Implemented"'';
UnusedOpensAnalyzer = true;
UnusedDeclarationsAnalyzer = true;
UseSdkScripts = true;
SimplifyNameAnalyzer = true;
ResolveNamespaces = true;
EnableReferenceCodeLens = true;
};
};
}; };
}; };
defaultFormat = "fantomas"; defaultFormat = ["fantomas"];
formats = { formats = {
fantomas = { fantomas = {
package = pkgs.fantomas; command = getExe pkgs.fantomas;
}; };
}; };
@ -52,33 +71,20 @@ in {
lsp = { lsp = {
enable = mkEnableOption "F# LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "F# LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.fsharp.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServer;
description = "F# LSP server to use"; description = "F# LSP server to use";
}; };
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
example = ''[lib.getExe pkgs.fsautocomplete "--state-directory" "~/.cache/fsautocomplete"]'';
description = "F# LSP server package, or the command to run as a list of strings";
};
}; };
format = { format = {
enable = mkEnableOption "F# formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "F# formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.fsharp.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "F# formatter to use"; description = "F# formatter to use";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "F# formatter package";
};
}; };
}; };
}; };
@ -90,16 +96,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.fsharp-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.fsharp = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.fsharp = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -7,28 +7,20 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.gleam; cfg = config.vim.languages.gleam;
defaultServer = "gleam"; defaultServers = ["gleam"];
servers = { servers = {
gleam = { gleam = {
package = pkgs.gleam; enable = true;
lspConfig = '' cmd = [(getExe pkgs.gleam) "lsp"];
lspconfig.gleam.setup{ filetypes = ["gleam"];
capabilities = capabilities, root_markers = ["gleam.toml" ".git"];
on_attach = default_on_attach,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/gleam", "lsp"}''
}
}
'';
}; };
}; };
in { in {
@ -42,18 +34,11 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Gleam LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Gleam LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.gleam.lsp.servers" (enum (attrNames servers));
type = enum (attrNames servers); default = defaultServers;
default = defaultServer;
description = "Gleam LSP server to use"; description = "Gleam LSP server to use";
}; };
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
description = "Gleam LSP server package, or the command to run as a list of strings";
};
}; };
}; };
@ -64,8 +49,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.gleam-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -8,45 +8,67 @@
inherit (lib.options) mkEnableOption mkOption literalMD; inherit (lib.options) mkEnableOption mkOption literalMD;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.lists) isList; inherit (lib.generators) mkLuaInline;
inherit (lib.types) bool enum either listOf package str; inherit (lib.types) bool enum package;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.go; cfg = config.vim.languages.go;
defaultServer = "gopls"; defaultServers = ["gopls"];
servers = { servers = {
gopls = { gopls = {
package = pkgs.gopls; cmd = [(getExe pkgs.gopls)];
lspConfig = '' filetypes = ["go" "gomod" "gowork" "gotmpl"];
lspconfig.gopls.setup { root_dir = mkLuaInline ''
capabilities = capabilities; function(bufnr, on_dir)
on_attach = default_on_attach; local fname = vim.api.nvim_buf_get_name(bufnr)
cmd = ${
if isList cfg.lsp.package local function get_root(fname)
then expToLua cfg.lsp.package if _G.nvf_gopls_mod_cache and fname:sub(1, #_G.nvf_gopls_mod_cache) == _G.nvf_gopls_mod_cache then
else ''{"${cfg.lsp.package}/bin/gopls", "serve"}'' local clients = vim.lsp.get_clients { name = 'gopls' }
}, if #clients > 0 then
} return clients[#clients].config.root_dir
end
end
return vim.fs.root(fname, 'go.work') or vim.fs.root(fname, 'go.mod') or vim.fs.root(fname, '.git')
end
-- see: https://github.com/neovim/nvim-lspconfig/issues/804
if _G.nvf_gopls_mod_cache then
on_dir(get_root(fname))
return
end
local cmd = { 'go', 'env', 'GOMODCACHE' }
local ok, err = pcall(vim.system, cmd, { text = true }, function(output)
if output.code == 0 then
if output.stdout then
_G.nvf_gopls_mod_cache = vim.trim(output.stdout)
end
on_dir(get_root(fname))
else
vim.schedule(function()
vim.notify(('[gopls] cmd failed with code %d: %s\n%s'):format(output.code, cmd, output.stderr))
end)
end
end)
if not ok then vim.notify(('[gopls] cmd failed: %s\n%s'):format(cmd, err)) end
end
''; '';
}; };
}; };
defaultFormat = "gofmt"; defaultFormat = ["gofmt"];
formats = { formats = {
gofmt = { gofmt = {
package = pkgs.go; command = "${pkgs.go}/bin/gofmt";
config.command = "${cfg.format.package}/bin/gofmt";
}; };
gofumpt = { gofumpt = {
package = pkgs.gofumpt; command = getExe pkgs.gofumpt;
config.command = getExe cfg.format.package;
}; };
golines = { golines = {
package = pkgs.golines; command = "${pkgs.golines}/bin/golines";
config.command = "${cfg.format.package}/bin/golines";
}; };
}; };
@ -69,17 +91,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Go LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Go LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.go.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Go LSP server to use"; description = "Go LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Go LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -95,15 +110,9 @@ in {
type = mkOption { type = mkOption {
description = "Go formatter to use"; description = "Go formatter to use";
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.go.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
}; };
package = mkOption {
description = "Go formatter package";
type = package;
default = formats.${cfg.format.type}.package;
};
}; };
dap = { dap = {
@ -134,15 +143,26 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.go-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.go = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = formats.${cfg.format.type}.config; formatters_by_ft.go = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
}; };
}) })

View file

@ -4,17 +4,64 @@
pkgs, pkgs,
... ...
}: let }: let
inherit (builtins) isList; inherit (builtins) isList attrNames;
inherit (lib.types) either package listOf str; inherit (lib.types) either package enum listOf str;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.meta) getExe';
inherit (lib.generators) mkLuaInline;
inherit (pkgs) haskellPackages; inherit (pkgs) haskellPackages;
cfg = config.vim.languages.haskell; cfg = config.vim.languages.haskell;
defaultServers = ["hls"];
servers = {
hls = {
enable = false;
cmd = [(getExe' pkgs.haskellPackages.haskell-language-server "haskell-language-server-wrapper") "--lsp"];
filetypes = ["haskell" "lhaskell"];
on_attach =
mkLuaInline
/*
lua
*/
''
function(client, bufnr)
local ht = require("haskell-tools")
local opts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set('n', '<localleader>cl', vim.lsp.codelens.run, opts)
vim.keymap.set('n', '<localleader>hs', ht.hoogle.hoogle_signature, opts)
vim.keymap.set('n', '<localleader>ea', ht.lsp.buf_eval_all, opts)
vim.keymap.set('n', '<localleader>rr', ht.repl.toggle, opts)
vim.keymap.set('n', '<localleader>rf', function()
ht.repl.toggle(vim.api.nvim_buf_get_name(0))
end, opts)
vim.keymap.set('n', '<localleader>rq', ht.repl.quit, opts)
end
'';
root_dir =
mkLuaInline
/*
lua
*/
''
function(bufnr, on_dir)
local fname = vim.api.nvim_buf_get_name(bufnr)
on_dir(util.root_pattern('hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml')(fname))
end
'';
settings = {
haskell = {
formattingProvider = "ormolu";
cabalFormattingProvider = "cabalfmt";
};
};
};
};
in { in {
options.vim.languages.haskell = { options.vim.languages.haskell = {
enable = mkEnableOption "Haskell support"; enable = mkEnableOption "Haskell support";
@ -25,21 +72,20 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "LSP support for Haskell" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Haskell LSP support" // {default = config.vim.lsp.enable;};
package = mkOption { servers = mkOption {
description = "Haskell LSP package or command to run the Haskell LSP"; type = listOf (enum (attrNames servers));
example = ''[ (lib.getExe pkgs.haskellPackages.haskell-language-server) "--debug" ]''; default = defaultServers;
default = haskellPackages.haskell-language-server; description = "Haskell LSP server to use";
type = either package (listOf str);
}; };
}; };
dap = { dap = {
enable = mkEnableOption "DAP support for Haskell" // {default = config.vim.languages.enableDAP;}; enable = mkEnableOption "DAP support for Haskell" // {default = config.vim.languages.enableDAP;};
package = mkOption { package = mkOption {
description = "Haskell DAP package or command to run the Haskell DAP";
default = haskellPackages.haskell-debug-adapter; default = haskellPackages.haskell-debug-adapter;
type = either package (listOf str); type = either package (listOf str);
description = "Haskell DAP package or command to run the Haskell DAP";
}; };
}; };
}; };
@ -57,7 +103,7 @@ in {
startPlugins = ["haskell-tools-nvim"]; startPlugins = ["haskell-tools-nvim"];
luaConfigRC.haskell-tools-nvim = luaConfigRC.haskell-tools-nvim =
entryAfter entryAfter
["lsp-setup"] ["lsp-servers"]
'' ''
vim.g.haskell_tools = { vim.g.haskell_tools = {
${optionalString cfg.lsp.enable '' ${optionalString cfg.lsp.enable ''
@ -67,31 +113,13 @@ in {
enable = true, enable = true,
}, },
}, },
hls = { hls = ${toLuaObject servers.hls},
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/haskell-language-server-wrapper", "--lsp"}''
},
on_attach = function(client, bufnr, ht)
default_on_attach(client, bufnr, ht)
local opts = { noremap = true, silent = true, buffer = bufnr }
vim.keymap.set('n', '<localleader>cl', vim.lsp.codelens.run, opts)
vim.keymap.set('n', '<localleader>hs', ht.hoogle.hoogle_signature, opts)
vim.keymap.set('n', '<localleader>ea', ht.lsp.buf_eval_all, opts)
vim.keymap.set('n', '<localleader>rr', ht.repl.toggle, opts)
vim.keymap.set('n', '<localleader>rf', function()
ht.repl.toggle(vim.api.nvim_buf_get_name(0))
end, opts)
vim.keymap.set('n', '<localleader>rq', ht.repl.quit, opts)
end,
},
''} ''}
${optionalString cfg.dap.enable '' ${optionalString cfg.dap.enable ''
dap = { dap = {
cmd = ${ cmd = ${
if isList cfg.dap.package if isList cfg.dap.package
then expToLua cfg.dap.package then toLuaObject cfg.dap.package
else ''{"${cfg.dap.package}/bin/haskell-debug-adapter"}'' else ''{"${cfg.dap.package}/bin/haskell-debug-adapter"}''
}, },
}, },

View file

@ -8,29 +8,26 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package bool enum; inherit (lib.types) bool enum listOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.hcl; cfg = config.vim.languages.hcl;
defaultServer = "terraform-ls"; defaultServers = ["terraform-ls"];
servers = { servers = {
terraform-ls = { terraform-ls = {
package = pkgs.terraform-ls; enable = true;
lspConfig = '' cmd = [(getExe pkgs.terraform-ls) "serve"];
lspconfig.terraformls.setup { filetypes = ["terraform" "terraform-vars"];
capabilities = capabilities, root_markers = [".terraform" ".git"];
on_attach=default_on_attach,
cmd = {"${lib.getExe cfg.lsp.package}", "serve"},
}
'';
}; };
}; };
defaultFormat = "hclfmt"; defaultFormat = ["hclfmt"];
formats = { formats = {
hclfmt = { hclfmt = {
package = pkgs.hclfmt; command = getExe pkgs.hclfmt;
}; };
}; };
in { in {
@ -43,12 +40,11 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "HCL LSP support (terraform-ls)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "HCL LSP support" // {default = config.vim.lsp.enable;};
# TODO: (maybe, is it better?) it would be cooler to use vscode-extensions.hashicorp.hcl probably, shouldn't be too hard servers = mkOption {
package = mkOption { type = listOf (enum (attrNames servers));
type = package; default = defaultServers;
default = servers.${defaultServer}.package; description = "HCL LSP server to use";
description = "HCL language server package (terraform-ls)";
}; };
}; };
@ -59,15 +55,10 @@ in {
description = "Enable HCL formatting"; description = "Enable HCL formatting";
}; };
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.hcl.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "HCL formatter to use"; description = "HCL formatter to use";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "HCL formatter package";
};
}; };
}; };
@ -96,18 +87,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources = lib.optionalAttrs (! config.vim.languages.terraform.lsp.enable) { mapListToAttrs (n: {
terraform-ls = servers.${cfg.lsp.server}.lspConfig; name = n;
}; value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.hcl = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.hcl = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -4,44 +4,39 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames head;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkDefault mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.helm; cfg = config.vim.languages.helm;
yamlCfg = config.vim.languages.yaml; yamlCfg = config.vim.languages.yaml;
helmCmd = defaultServers = ["helm-ls"];
if isList cfg.lsp.package
then cfg.lsp.package
else ["${cfg.lsp.package}/bin/helm_ls" "serve"];
yamlCmd =
if isList yamlCfg.lsp.package
then builtins.elemAt yamlCfg.lsp.package 0
else "${yamlCfg.lsp.package}/bin/yaml-language-server";
defaultServer = "helm-ls";
servers = { servers = {
helm-ls = { helm-ls = {
package = pkgs.helm-ls; enable = true;
lspConfig = '' cmd = [(getExe pkgs.helm-ls) "serve"];
lspconfig.helm_ls.setup { filetypes = ["helm" "yaml.helm-values"];
capabilities = capabilities, root_markers = ["Chart.yaml"];
on_attach = default_on_attach, capabilities = {
cmd = ${expToLua helmCmd}, didChangeWatchedFiles = {
settings = { dynamicRegistration = true;
['helm-ls'] = { };
yamlls = { };
path = "${yamlCmd}" settings = mkIf (yamlCfg.enable && yamlCfg.lsp.enable) {
} helm-ls = {
} yamlls = {
} # Without this being enabled, the YAML language module will look broken in helmfiles
} # if both modules are enabled at once.
''; enabled = mkDefault yamlCfg.lsp.enable;
path = head config.vim.lsp.servers.${head yamlCfg.lsp.servers}.cmd;
};
};
};
}; };
}; };
in { in {
@ -55,17 +50,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Helm LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Helm LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.helm.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Helm LSP server to use"; description = "Helm LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Helm LSP server package";
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
}; };
@ -77,8 +65,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.helm-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
{ {

View file

@ -4,14 +4,46 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames;
inherit (lib.meta) getExe;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) bool; inherit (lib.types) bool enum;
inherit (lib.lists) optional; inherit (lib.lists) optional;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption diagnostics deprecatedSingleOrListOf;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.html; cfg = config.vim.languages.html;
defaultServers = ["superhtml"];
servers = {
superhtml = {
cmd = [(getExe pkgs.superhtml) "lsp"];
filetypes = ["html" "shtml" "htm"];
root_markers = ["index.html" ".git"];
};
emmet-ls = {
cmd = [(getExe pkgs.emmet-ls) "--stdio"];
filetypes = ["html" "shtml" "htm"];
root_markers = ["index.html" ".git"];
};
};
defaultFormat = ["superhtml"];
formats = {
superhtml = {
command = "${pkgs.superhtml}/bin/superhtml";
args = ["fmt" "-"];
};
};
defaultDiagnosticsProvider = ["htmlhint"];
diagnosticsProviders = {
htmlhint = {
config.cmd = getExe pkgs.htmlhint;
};
};
in { in {
options.vim.languages.html = { options.vim.languages.html = {
enable = mkEnableOption "HTML language support"; enable = mkEnableOption "HTML language support";
@ -19,9 +51,38 @@ in {
enable = mkEnableOption "HTML treesitter support" // {default = config.vim.languages.enableTreesitter;}; enable = mkEnableOption "HTML treesitter support" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "html"; package = mkGrammarOption pkgs "html";
autotagHtml = mkOption { autotagHtml = mkOption {
description = "Enable autoclose/autorename of html tags (nvim-ts-autotag)";
type = bool; type = bool;
default = true; default = true;
description = "Enable autoclose/autorename of html tags (nvim-ts-autotag)";
};
};
lsp = {
enable = mkEnableOption "HTML LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.html.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "HTML LSP server to use";
};
};
format = {
enable = mkEnableOption "HTML formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption {
type = deprecatedSingleOrListOf "vim.language.html.format.type" (enum (attrNames formats));
default = defaultFormat;
description = "HTML formatter to use";
};
};
extraDiagnostics = {
enable = mkEnableOption "extra HTML diagnostics" // {default = config.vim.languages.enableExtraDiagnostics;};
types = diagnostics {
langDesc = "HTML";
inherit diagnosticsProviders;
inherit defaultDiagnosticsProvider;
}; };
}; };
}; };
@ -41,5 +102,40 @@ in {
''); '');
}; };
}) })
(mkIf cfg.lsp.enable {
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
})
(mkIf (cfg.format.enable && !cfg.lsp.enable) {
vim.formatter.conform-nvim = {
enable = true;
setupOpts = {
formatters_by_ft.html = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
};
})
(mkIf cfg.extraDiagnostics.enable {
vim.diagnostics.nvim-lint = {
enable = true;
linters_by_ft.html = cfg.extraDiagnostics.types;
linters = mkMerge (map (name: {
${name} = diagnosticsProviders.${name}.config;
})
cfg.extraDiagnostics.types);
};
})
]); ]);
} }

View file

@ -7,12 +7,59 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.lists) isList; inherit (builtins) attrNames;
inherit (lib.types) either listOf package str; inherit (lib.types) listOf enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryBefore;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.java; cfg = config.vim.languages.java;
defaultServers = ["jdtls"];
servers = {
jdtls = {
enable = true;
cmd =
mkLuaInline
/*
lua
*/
''
{
'${getExe pkgs.jdt-language-server}',
'-configuration',
get_jdtls_config_dir(),
'-data',
get_jdtls_workspace_dir(),
get_jdtls_jvm_args(),
}
'';
filetypes = ["java"];
root_markers = [
# Multi-module projects
".git"
"build.gradle"
"build.gradle.kts"
# Single-module projects
"build.xml" # Ant
"pom.xml" # Maven
"settings.gradle" # Gradle
"settings.gradle.kts" # Gradle
];
init_options = {
workspace = mkLuaInline "get_jdtls_workspace_dir()";
jvm_args = {};
os_config = mkLuaInline "nil";
};
handlers = {
"textDocument/codeAction" = mkLuaInline "jdtls_on_textdocument_codeaction";
"textDocument/rename" = mkLuaInline "jdtls_on_textdocument_rename";
"workspace/applyEdit" = mkLuaInline "jdtls_on_workspace_applyedit";
"language/status" = mkLuaInline "vim.schedule_wrap(jdtls_on_language_status)";
};
};
};
in { in {
options.vim.languages.java = { options.vim.languages.java = {
enable = mkEnableOption "Java language support"; enable = mkEnableOption "Java language support";
@ -23,30 +70,107 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Java LSP support (java-language-server)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Java LSP support" // {default = config.vim.lsp.enable;};
package = mkOption { servers = mkOption {
description = "java language server package, or the command to run as a list of strings"; type = listOf (enum (attrNames servers));
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]''; default = defaultServers;
type = either package (listOf str); description = "Java LSP server to use";
default = pkgs.jdt-language-server;
}; };
}; };
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.luaConfigRC.jdtls-util =
vim.lsp.lspconfig.sources.jdtls = '' entryBefore ["lsp-servers"]
lspconfig.jdtls.setup { /*
capabilities = capabilities, lua
on_attach = default_on_attach, */
cmd = ${ ''
if isList cfg.lsp.package local jdtls_handlers = require 'vim.lsp.handlers'
then expToLua cfg.lsp.package
else ''{"${getExe cfg.lsp.package}", "-data", vim.fn.stdpath("cache").."/jdtls/workspace"}'' local jdtls_env = {
}, HOME = vim.uv.os_homedir(),
} XDG_CACHE_HOME = os.getenv 'XDG_CACHE_HOME',
''; JDTLS_JVM_ARGS = os.getenv 'JDTLS_JVM_ARGS',
}
local function get_cache_dir()
return jdtls_env.XDG_CACHE_HOME and jdtls_env.XDG_CACHE_HOME or jdtls_env.HOME .. '/.cache'
end
local function get_jdtls_cache_dir()
return get_cache_dir() .. '/jdtls'
end
local function get_jdtls_config_dir()
return get_jdtls_cache_dir() .. '/config'
end
local function get_jdtls_workspace_dir()
return get_jdtls_cache_dir() .. '/workspace'
end
local function get_jdtls_jvm_args()
local args = {}
for a in string.gmatch((jdtls_env.JDTLS_JVM_ARGS or '''), '%S+') do
local arg = string.format('--jvm-arg=%s', a)
table.insert(args, arg)
end
return unpack(args)
end
-- TextDocument version is reported as 0, override with nil so that
-- the client doesn't think the document is newer and refuses to update
-- See: https://github.com/eclipse/eclipse.jdt.ls/issues/1695
local function jdtls_fix_zero_version(workspace_edit)
if workspace_edit and workspace_edit.documentChanges then
for _, change in pairs(workspace_edit.documentChanges) do
local text_document = change.textDocument
if text_document and text_document.version and text_document.version == 0 then
text_document.version = nil
end
end
end
return workspace_edit
end
local function jdtls_on_textdocument_codeaction(err, actions, ctx)
for _, action in ipairs(actions) do
-- TODO: (steelsojka) Handle more than one edit?
if action.command == 'java.apply.workspaceEdit' then -- 'action' is Command in java format
action.edit = jdtls_fix_zero_version(action.edit or action.arguments[1])
elseif type(action.command) == 'table' and action.command.command == 'java.apply.workspaceEdit' then -- 'action' is CodeAction in java format
action.edit = jdtls_fix_zero_version(action.edit or action.command.arguments[1])
end
end
jdtls_handlers[ctx.method](err, actions, ctx)
end
local function jdtls_on_textdocument_rename(err, workspace_edit, ctx)
jdtls_handlers[ctx.method](err, jdtls_fix_zero_version(workspace_edit), ctx)
end
local function jdtls_on_workspace_applyedit(err, workspace_edit, ctx)
jdtls_handlers[ctx.method](err, jdtls_fix_zero_version(workspace_edit), ctx)
end
-- Non-standard notification that can be used to display progress
local function jdtls_on_language_status(_, result)
local command = vim.api.nvim_command
command 'echohl ModeMsg'
command(string.format('echo "%s"', result.message))
command 'echohl None'
end
'';
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {

View file

@ -0,0 +1,96 @@
{
config,
pkgs,
lib,
...
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.meta) getExe' getExe;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.json;
defaultServers = ["jsonls"];
servers = {
jsonls = {
cmd = [(getExe' pkgs.vscode-langservers-extracted "vscode-json-language-server") "--stdio"];
filetypes = ["json" "jsonc"];
init_options = {provideFormatter = true;};
root_markers = [".git"];
};
};
defaultFormat = ["jsonfmt"];
formats = {
jsonfmt = {
command = getExe pkgs.jsonfmt;
args = ["-w" "-"];
};
};
in {
options.vim.languages.json = {
enable = mkEnableOption "JSON language support";
treesitter = {
enable = mkEnableOption "JSON treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "json";
};
lsp = {
enable = mkEnableOption "JSON LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.json.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "JSON LSP server to use";
};
};
format = {
enable = mkEnableOption "JSON formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption {
description = "JSON formatter to use";
type = deprecatedSingleOrListOf "vim.language.json.format.type" (enum (attrNames formats));
default = defaultFormat;
};
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package];
})
(mkIf cfg.lsp.enable {
vim.lsp.servers =
mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf cfg.format.enable {
vim.formatter.conform-nvim = {
enable = true;
setupOpts = {
formatters_by_ft.json = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
};
})
]);
}

View file

@ -4,63 +4,82 @@
config, config,
... ...
}: let }: let
inherit (builtins) attrNames isList; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) either listOf package str enum bool nullOr; inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.strings) optionalString; inherit (lib.meta) getExe;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryBefore;
defaultServer = "julials"; defaultServers = ["julials"];
servers = { servers = {
julials = { julials = {
package = pkgs.julia.withPackages ["LanguageServer"]; enable = true;
internalFormatter = true; cmd =
lspConfig = '' mkLuaInline
lspconfig.julials.setup { /*
capabilities = capabilities, lua
on_attach = default_on_attach, */
cmd = ${ ''
if isList cfg.lsp.package {
then expToLua cfg.lsp.package '${getExe (pkgs.julia.withPackages ["LanguageServer"])}',
else '' '--startup-file=no',
{ '--history-file=no',
"${optionalString (cfg.lsp.package != null) "${cfg.lsp.package}/bin/"}julia", '-e',
"--startup-file=no", [[
"--history-file=no", # Load LanguageServer.jl: attempt to load from ~/.julia/environments/nvim-lspconfig
"--eval", # with the regular load path as a fallback
[[ ls_install_path = joinpath(
using LanguageServer get(DEPOT_PATH, 1, joinpath(homedir(), ".julia")),
"environments", "nvim-lspconfig"
depot_path = get(ENV, "JULIA_DEPOT_PATH", "") )
project_path = let pushfirst!(LOAD_PATH, ls_install_path)
dirname(something( using LanguageServer
## 1. Finds an explicitly set project (JULIA_PROJECT) popfirst!(LOAD_PATH)
Base.load_path_expand(( depot_path = get(ENV, "JULIA_DEPOT_PATH", "")
p = get(ENV, "JULIA_PROJECT", nothing); project_path = let
p === nothing ? nothing : isempty(p) ? nothing : p dirname(something(
)), ## 1. Finds an explicitly set project (JULIA_PROJECT)
## 2. Look for a Project.toml file in the current working directory, Base.load_path_expand((
## or parent directories, with $HOME as an upper boundary p = get(ENV, "JULIA_PROJECT", nothing);
Base.current_project(), p === nothing ? nothing : isempty(p) ? nothing : p
## 3. First entry in the load path )),
get(Base.load_path(), 1, nothing), ## 2. Look for a Project.toml file in the current working directory,
## 4. Fallback to default global environment, ## or parent directories, with $HOME as an upper boundary
## this is more or less unreachable Base.current_project(),
Base.load_path_expand("@v#.#"), ## 3. First entry in the load path
)) get(Base.load_path(), 1, nothing),
end ## 4. Fallback to default global environment,
@info "Running language server" VERSION pwd() project_path depot_path ## this is more or less unreachable
server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path) Base.load_path_expand("@v#.#"),
server.runlinter = true ))
run(server) end
]] @info "Running language server" VERSION pwd() project_path depot_path
} server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path)
'' server.runlinter = true
} run(server)
} ]],
''; }
'';
filetypes = ["julia"];
root_markers = ["Project.toml" "JuliaProject.toml"];
on_attach =
mkLuaInline
/*
lua
*/
''
function(_, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspJuliaActivateEnv', activate_julia_env, {
desc = 'Activate a Julia environment',
nargs = '?',
complete = 'file',
})
end
'';
}; };
}; };
@ -76,38 +95,26 @@ in {
}; };
lsp = { lsp = {
enable = mkOption { enable = mkEnableOption "Julia LSP support" // {default = config.vim.lsp.enable;};
type = bool; servers = mkOption {
default = config.vim.lsp.enable; type = deprecatedSingleOrListOf "vim.language.julia.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = '' description = ''
Whether to enable Julia LSP support. Julia LSP Server to Use
::: {.note} ::: {.note}
The entirety of Julia is bundled with nvf, if you enable this The entirety of Julia is bundled with nvf, if you enable this
option, since there is no way to provide only the LSP server. option, since there is no way to provide only the LSP server.
If you want to avoid that, you have to change If you want to avoid that, you have to change
[](#opt-vim.languages.julia.lsp.package) to use the Julia binary [vim.lsp.servers.julials.cmd](#opt-vim.lsp.servers._name_.cmd) to use
in {env}`PATH` (set it to `null`), and add the `LanguageServer` package to the Julia binary in {env}`PATH`, and add the `LanguageServer`
Julia in your devshells. package to Julia in your devshells.
Check the source file of this option for the full `cmd`.
::: :::
''; '';
}; };
server = mkOption {
type = enum (attrNames servers);
default = defaultServer;
description = "Julia LSP server to use";
};
package = mkOption {
description = ''
Julia LSP server package, `null` to use the Julia binary in {env}`PATH`, or
the command to run as a list of strings.
'';
type = nullOr (either package (listOf str));
default = servers.${cfg.lsp.server}.package;
};
}; };
}; };
}; };
@ -119,8 +126,70 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.luaConfigRC.julia-util =
vim.lsp.lspconfig.sources.julia-lsp = servers.${cfg.lsp.server}.lspConfig; entryBefore ["lsp-servers"]
/*
lua
*/
''
local function activate_julia_env(path)
assert(vim.fn.has 'nvim-0.10' == 1, 'requires Nvim 0.10 or newer')
local bufnr = vim.api.nvim_get_current_buf()
local julials_clients = vim.lsp.get_clients { bufnr = bufnr, name = 'julials' }
assert(
#julials_clients > 0,
'method julia/activateenvironment is not supported by any servers active on the current buffer'
)
local function _activate_env(environment)
if environment then
for _, julials_client in ipairs(julials_clients) do
julials_client:notify('julia/activateenvironment', { envPath = environment })
end
vim.notify('Julia environment activated: \n`' .. environment .. '`', vim.log.levels.INFO)
end
end
if path then
path = vim.fs.normalize(vim.fn.fnamemodify(vim.fn.expand(path), ':p'))
local found_env = false
for _, project_file in ipairs(root_files) do
local file = vim.uv.fs_stat(vim.fs.joinpath(path, project_file))
if file and file.type then
found_env = true
break
end
end
if not found_env then
vim.notify('Path is not a julia environment: \n`' .. path .. '`', vim.log.levels.WARN)
return
end
_activate_env(path)
else
local depot_paths = vim.env.JULIA_DEPOT_PATH
and vim.split(vim.env.JULIA_DEPOT_PATH, vim.fn.has 'win32' == 1 and ';' or ':')
or { vim.fn.expand '~/.julia' }
local environments = {}
vim.list_extend(environments, vim.fs.find(root_files, { type = 'file', upward = true, limit = math.huge }))
for _, depot_path in ipairs(depot_paths) do
local depot_env = vim.fs.joinpath(vim.fs.normalize(depot_path), 'environments')
vim.list_extend(
environments,
vim.fs.find(function(name, env_path)
return vim.tbl_contains(root_files, name) and string.sub(env_path, #depot_env + 1):match '^/[^/]*$'
end, { path = depot_env, type = 'file', limit = math.huge })
)
end
environments = vim.tbl_map(vim.fs.dirname, environments)
vim.ui.select(environments, { prompt = 'Select a Julia environment' }, _activate_env)
end
end
'';
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -0,0 +1,64 @@
{
config,
lib,
pkgs,
...
}: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) mkGrammarOption;
cfg = config.vim.languages.just;
defaultServers = ["just-lsp"];
servers = {
just-lsp = {
enable = true;
cmd = [(getExe pkgs.just-lsp)];
filetypes = ["just"];
root_markers = [".git" "justfile"];
};
};
in {
options.vim.languages.just = {
enable = mkEnableOption "Just support";
treesitter = {
enable =
mkEnableOption "Just treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "just";
};
lsp = {
enable =
mkEnableOption "Just LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = listOf (enum (attrNames servers));
default = defaultServers;
description = "Just LSP server to use";
};
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter = {
enable = true;
grammars = [cfg.treesitter.package];
};
})
(mkIf cfg.lsp.enable {
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
})
]);
}

View file

@ -4,16 +4,47 @@
lib, lib,
... ...
}: let }: let
inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe' getExe;
inherit (lib.types) either package listOf str; inherit (builtins) attrNames;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.lists) isList; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.kotlin; cfg = config.vim.languages.kotlin;
defaultServers = ["kotlin-language-server"];
servers = {
kotlin-language-server = {
enable = true;
cmd = [(getExe' pkgs.kotlin-language-server "kotlin-language-server")];
filetypes = ["kotlin"];
root_markers = [
"settings.gradle" # Gradle (multi-project)
"settings.gradle.kts" # Gradle (multi-project)
"build.xml" # Ant
"pom.xml" # Maven
"build.gradle" # Gradle
"build.gradle.kts" # gradle
];
init_options = {
storagePath = mkLuaInline "
vim.fs.root(vim.fn.expand '%:p:h',
{
'settings.gradle', -- Gradle (multi-project)
'settings.gradle.kts', -- Gradle (multi-project)
'build.xml', -- Ant
'pom.xml', -- Maven
'build.gradle', -- Gradle
'build.gradle.kts', -- Gradle
}
)";
};
};
};
defaultDiagnosticsProvider = ["ktlint"]; defaultDiagnosticsProvider = ["ktlint"];
diagnosticsProviders = { diagnosticsProviders = {
ktlint = { ktlint = {
@ -31,22 +62,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Kotlin LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Kotlin LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
package = mkOption { type = listOf (enum (attrNames servers));
description = "kotlin_language_server package with Kotlin runtime"; default = defaultServers;
type = either package (listOf str); description = "Kotlin LSP server to use";
example = literalExpression ''
pkgs.symlinkJoin {
name = "kotlin-language-server-wrapped";
paths = [pkgs.kotlin-language-server];
nativeBuildInputs = [pkgs.makeBinaryWrapper];
postBuild = '''
wrapProgram $out/bin/kotlin-language-server \
--prefix PATH : ''${pkgs.kotlin}/bin
''';
};
'';
default = pkgs.kotlin-language-server;
}; };
}; };
@ -78,23 +97,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.kotlin_language_server = '' mapListToAttrs (n: {
lspconfig.kotlin_language_server.setup { name = n;
capabilities = capabilities, value = servers.${n};
root_dir = lspconfig.util.root_pattern("main.kt", ".git"), })
on_attach=default_on_attach, cfg.lsp.servers;
init_options = {
-- speeds up the startup time for the LSP
storagePath = vim.fn.stdpath('state') .. '/kotlin',
},
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/kotlin-language-server"}''
},
}
'';
}) })
]); ]);
} }

View file

@ -8,17 +8,36 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.lists) isList; inherit (lib.types) bool enum listOf;
inherit (lib.types) bool either enum listOf package str; inherit (lib.nvim.types) diagnostics mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) diagnostics mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
inherit (lib.nvim.dag) entryBefore; inherit (lib.nvim.dag) entryBefore;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.lua; cfg = config.vim.languages.lua;
defaultFormat = "stylua";
defaultServers = ["lua-language-server"];
servers = {
lua-language-server = {
enable = true;
cmd = [(getExe pkgs.lua-language-server)];
filetypes = ["lua"];
root_markers = [
".luarc.json"
".luarc.jsonc"
".luacheckrc"
".stylua.toml"
"stylua.toml"
"selene.toml"
"selene.yml"
".git"
];
};
};
defaultFormat = ["stylua"];
formats = { formats = {
stylua = { stylua = {
package = pkgs.stylua; command = getExe pkgs.stylua;
}; };
}; };
@ -43,12 +62,11 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Lua LSP support via LuaLS" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Lua LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
package = mkOption { type = listOf (enum (attrNames servers));
description = "LuaLS package, or the command to run as a list of strings"; default = defaultServers;
type = either package (listOf str); description = "Lua LSP server to use";
default = pkgs.lua-language-server;
}; };
lazydev.enable = mkEnableOption "lazydev.nvim integration, useful for neovim plugin developers"; lazydev.enable = mkEnableOption "lazydev.nvim integration, useful for neovim plugin developers";
@ -61,16 +79,10 @@ in {
description = "Enable Lua formatting"; description = "Enable Lua formatting";
}; };
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.lua.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "Lua formatter to use"; description = "Lua formatter to use";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "Lua formatter package";
};
}; };
extraDiagnostics = { extraDiagnostics = {
@ -91,23 +103,17 @@ in {
(mkIf cfg.enable (mkMerge [ (mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.lua-lsp = '' mapListToAttrs (n: {
lspconfig.lua_ls.setup { name = n;
capabilities = capabilities; value = servers.${n};
on_attach = default_on_attach; })
cmd = ${ cfg.lsp.servers;
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${getExe cfg.lsp.package}"}''
};
}
'';
}) })
(mkIf cfg.lsp.lazydev.enable { (mkIf cfg.lsp.lazydev.enable {
vim.startPlugins = ["lazydev-nvim"]; vim.startPlugins = ["lazydev-nvim"];
vim.pluginRC.lazydev = entryBefore ["lua-lsp"] '' vim.pluginRC.lazydev = entryBefore ["lsp-servers"] ''
require("lazydev").setup({ require("lazydev").setup({
enabled = function(root_dir) enabled = function(root_dir)
return not vim.uv.fs_stat(root_dir .. "/.luarc.json") return not vim.uv.fs_stat(root_dir .. "/.luarc.json")
@ -120,9 +126,14 @@ in {
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.lua = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.lua = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -8,42 +8,42 @@
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.lists) isList; inherit (lib.types) bool enum listOf str nullOr;
inherit (lib.types) bool enum either package listOf str nullOr; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.lua) expToLua toLuaObject; inherit (lib.nvim.types) diagnostics mkGrammarOption mkPluginSetupOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) diagnostics mkGrammarOption mkPluginSetupOption;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.trivial) warn;
cfg = config.vim.languages.markdown; cfg = config.vim.languages.markdown;
defaultServer = "marksman"; defaultServers = ["marksman"];
servers = { servers = {
marksman = { marksman = {
package = pkgs.marksman; enable = true;
lspConfig = '' cmd = [(getExe pkgs.marksman) "server"];
lspconfig.marksman.setup{ filetypes = ["markdown" "markdown.mdx"];
capabilities = capabilities; root_markers = [".marksman.toml" ".git"];
on_attach = default_on_attach; };
cmd = ${
if isList cfg.lsp.package markdown-oxide = {
then expToLua cfg.lsp.package enable = true;
else ''{"${cfg.lsp.package}/bin/marksman", "server"}'' cmd = [(getExe pkgs.markdown-oxide)];
}, filetypes = ["markdown"];
} root_markers = [".git" ".obsidian" ".moxide.toml"];
'';
}; };
}; };
defaultFormat = "deno_fmt"; defaultFormat = ["deno_fmt"];
formats = { formats = {
# for backwards compatibility # for backwards compatibility
denofmt = { denofmt = {
package = pkgs.deno; command = getExe pkgs.deno;
}; };
deno_fmt = { deno_fmt = {
package = pkgs.deno; command = getExe pkgs.deno;
}; };
prettierd = { prettierd = {
package = pkgs.prettierd; command = getExe pkgs.prettierd;
}; };
}; };
defaultDiagnosticsProvider = ["markdownlint-cli2"]; defaultDiagnosticsProvider = ["markdownlint-cli2"];
@ -67,19 +67,12 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "Enable Markdown LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Markdown LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers);
default = defaultServer;
description = "Markdown LSP server to use"; description = "Markdown LSP server to use";
}; type = deprecatedSingleOrListOf "vim.language.markdown.lsp.servers" (enum (attrNames servers));
default = defaultServers;
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
description = "Markdown LSP server package, or the command to run as a list of strings";
}; };
}; };
@ -87,17 +80,11 @@ in {
enable = mkEnableOption "Markdown formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Markdown formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.markdown.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "Markdown formatter to use. `denofmt` is deprecated and currently aliased to deno_fmt."; description = "Markdown formatter to use. `denofmt` is deprecated and currently aliased to deno_fmt.";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "Markdown formatter package";
};
extraFiletypes = mkOption { extraFiletypes = mkOption {
type = listOf str; type = listOf str;
default = []; default = [];
@ -161,20 +148,34 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.markdown-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.markdown = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${ formatters_by_ft.markdown = cfg.format.type;
if cfg.format.type == "denofmt" formatters = let
then "deno_fmt" names = map (name:
else cfg.format.type if name == "denofmt"
} = { then
command = getExe cfg.format.package; warn ''
vim.languages.markdown.format.type: "denofmt" is renamed to "deno_fmt".
'' "deno_fmt"
else name)
cfg.format.type;
in
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
names;
}; };
}; };
}) })

View file

@ -6,41 +6,41 @@
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe';
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) enum either listOf package str; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.nim; cfg = config.vim.languages.nim;
defaultServer = "nimlsp"; defaultServers = ["nimlsp"];
servers = { servers = {
nimlsp = { nimlsp = {
package = pkgs.nimlsp; enable = true;
lspConfig = '' cmd = [(getExe' pkgs.nimlsp "nimlsp")];
lspconfig.nimls.setup{ filetypes = ["nim"];
capabilities = capabilities; root_dir =
on_attach = default_on_attach; mkLuaInline
cmd = ${ /*
if isList cfg.lsp.package lua
then expToLua cfg.lsp.package */
else '' ''
{"${cfg.lsp.package}/bin/nimlsp"} function(bufnr, on_dir)
'' local fname = vim.api.nvim_buf_get_name(bufnr)
}; on_dir(
} util.root_pattern '*.nimble'(fname) or vim.fs.dirname(vim.fs.find('.git', { path = fname, upward = true })[1])
''; )
end
'';
}; };
}; };
defaultFormat = "nimpretty"; defaultFormat = ["nimpretty"];
formats = { formats = {
nimpretty = { nimpretty = {
package = pkgs.nim; command = "${pkgs.nim}/bin/nimpretty";
config = {
command = "${cfg.format.package}/bin/nimpretty";
};
}; };
}; };
in { in {
@ -54,32 +54,20 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Nim LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Nim LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
description = "Nim LSP server to use";
type = str;
default = defaultServer;
};
package = mkOption { servers = mkOption {
description = "Nim LSP server package, or the command to run as a list of strings"; type = deprecatedSingleOrListOf "vim.language.nim.lsp.servers" (enum (attrNames servers));
example = ''[lib.getExe pkgs.nimlsp]''; default = defaultServers;
type = either package (listOf str); description = "Nim LSP server to use";
default = servers.${cfg.lsp.server}.package;
}; };
}; };
format = { format = {
enable = mkEnableOption "Nim formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Nim formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Nim formatter to use"; type = deprecatedSingleOrListOf "vim.language.nim.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Nim formatter to use";
package = mkOption {
description = "Nim formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
}; };
@ -100,15 +88,26 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.nim-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.nim = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = formats.${cfg.format.type}.config; formatters_by_ft.nim = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
}; };
}) })
]); ]);

View file

@ -9,93 +9,37 @@
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.strings) optionalString; inherit (lib.nvim.types) mkGrammarOption diagnostics deprecatedSingleOrListOf;
inherit (lib.types) anything attrsOf enum either listOf nullOr package str; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.nvim.lua) expToLua toLuaObject;
cfg = config.vim.languages.nix; cfg = config.vim.languages.nix;
useFormat = "on_attach = default_on_attach"; defaultServers = ["nil"];
noFormat = "on_attach = attach_keymaps";
defaultServer = "nil";
packageToCmd = package: defaultCmd:
if isList package
then expToLua package
else ''{"${package}/bin/${defaultCmd}"}'';
servers = { servers = {
nil = { nil = {
package = pkgs.nil; enable = true;
internalFormatter = true; cmd = [(getExe pkgs.nil)];
lspConfig = '' filetypes = ["nix"];
lspconfig.nil_ls.setup{ root_markers = [".git" "flake.nix"];
capabilities = capabilities,
${
if cfg.format.enable
then useFormat
else noFormat
},
cmd = ${packageToCmd cfg.lsp.package "nil"},
${optionalString cfg.format.enable ''
settings = {
["nil"] = {
${optionalString (cfg.format.type == "alejandra")
''
formatting = {
command = {"${cfg.format.package}/bin/alejandra", "--quiet"},
},
''}
${optionalString (cfg.format.type == "nixfmt")
''
formatting = {
command = {"${cfg.format.package}/bin/nixfmt"},
},
''}
},
},
''}
}
'';
}; };
nixd = let nixd = {
settings.nixd = { enable = true;
inherit (cfg.lsp) options; cmd = [(getExe pkgs.nixd)];
formatting.command = filetypes = ["nix"];
if !cfg.format.enable root_markers = [".git" "flake.nix"];
then null
else if cfg.format.type == "alejandra"
then ["${cfg.format.package}/bin/alejandra" "--quiet"]
else ["${cfg.format.package}/bin/nixfmt"];
};
in {
package = pkgs.nixd;
internalFormatter = true;
lspConfig = ''
lspconfig.nixd.setup{
capabilities = capabilities,
${
if cfg.format.enable
then useFormat
else noFormat
},
cmd = ${packageToCmd cfg.lsp.package "nixd"},
settings = ${toLuaObject settings},
}
'';
}; };
}; };
defaultFormat = "alejandra"; defaultFormat = ["alejandra"];
formats = { formats = {
alejandra = { alejandra = {
package = pkgs.alejandra; command = getExe pkgs.alejandra;
}; };
nixfmt = { nixfmt = {
package = pkgs.nixfmt-rfc-style; command = getExe pkgs.nixfmt-rfc-style;
}; };
}; };
@ -136,23 +80,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Nix LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Nix LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.nix.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Nix LSP server to use"; description = "Nix LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Nix LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
};
options = mkOption {
type = nullOr (attrsOf anything);
default = null;
description = "Options to pass to nixd LSP server";
}; };
}; };
@ -161,15 +92,9 @@ in {
type = mkOption { type = mkOption {
description = "Nix formatter to use"; description = "Nix formatter to use";
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.nix.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
}; };
package = mkOption {
description = "Nix formatter package";
type = package;
default = formats.${cfg.format.type}.package;
};
}; };
extraDiagnostics = { extraDiagnostics = {
@ -193,13 +118,6 @@ in {
${concatStringsSep ", " (attrNames formats)} ${concatStringsSep ", " (attrNames formats)}
''; '';
} }
{
assertion = cfg.lsp.server != "rnix";
message = ''
rnix-lsp has been archived upstream. Please use one of the following available language servers:
${concatStringsSep ", " (attrNames servers)}
'';
}
]; ];
} }
@ -209,16 +127,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.nix-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf (cfg.format.enable && (!cfg.lsp.enable || !servers.${cfg.lsp.server}.internalFormatter)) { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.nix = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.nix = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -5,27 +5,30 @@
... ...
}: let }: let
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) str either package listOf; inherit (lib.types) enum;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.meta) getExe;
inherit (builtins) isList; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (builtins) attrNames;
defaultServer = "nushell"; defaultServers = ["nushell"];
servers = { servers = {
nushell = { nushell = {
package = pkgs.nushell; enable = true;
lspConfig = '' cmd = [(getExe pkgs.nushell) "--no-config-file" "--lsp"];
lspconfig.nushell.setup{ filetypes = ["nu"];
capabilities = capabilities, root_dir =
on_attach = default_on_attach, mkLuaInline
cmd = ${ /*
if isList cfg.lsp.package lua
then expToLua cfg.lsp.package */
else ''{"${cfg.lsp.package}/bin/nu", "--no-config-file", "--lsp"}'' ''
} function(bufnr, on_dir)
} on_dir(vim.fs.root(bufnr, { '.git' }) or vim.fs.dirname(vim.api.nvim_buf_get_name(bufnr)))
''; end
'';
}; };
}; };
@ -41,17 +44,11 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Nu LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Nu LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
type = str;
default = defaultServer;
description = "Nu LSP server to use";
};
package = mkOption { servers = mkOption {
type = either package (listOf str); type = deprecatedSingleOrListOf "vim.language.nu.lsp.servers" (enum (attrNames servers));
default = servers.${cfg.lsp.server}.package; default = defaultServers;
example = ''[(lib.getExe pkgs.nushell) "--lsp"]''; description = "Nu LSP server to use";
description = "Nu LSP server package, or the command to run as a list of strings";
}; };
}; };
}; };
@ -63,8 +60,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.nu-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -8,35 +8,57 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) either enum listOf package str; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.ocaml; cfg = config.vim.languages.ocaml;
defaultServer = "ocaml-lsp"; defaultServers = ["ocaml-lsp"];
servers = { servers = {
ocaml-lsp = { ocaml-lsp = {
package = pkgs.ocamlPackages.ocaml-lsp; enable = true;
lspConfig = '' cmd = [(getExe pkgs.ocamlPackages.ocaml-lsp)];
lspconfig.ocamllsp.setup { filetypes = ["ocaml" "menhir" "ocamlinterface" "ocamllex" "reason" "dune"];
capabilities = capabilities, root_dir =
on_attach = default_on_attach, mkLuaInline
cmd = ${ /*
if isList cfg.lsp.package lua
then expToLua cfg.lsp.package */
else ''{"${getExe cfg.lsp.package}"}'' ''
}; function(bufnr, on_dir)
} local fname = vim.api.nvim_buf_get_name(bufnr)
''; on_dir(util.root_pattern('*.opam', 'esy.json', 'package.json', '.git', 'dune-project', 'dune-workspace')(fname))
end
'';
get_language_id =
mkLuaInline
/*
lua
*/
''
function(_, ftype)
local language_id_of = {
menhir = 'ocaml.menhir',
ocaml = 'ocaml',
ocamlinterface = 'ocaml.interface',
ocamllex = 'ocaml.ocamllex',
reason = 'reason',
dune = 'dune',
}
return language_id_of[ftype]
end
'';
}; };
}; };
defaultFormat = "ocamlformat"; defaultFormat = ["ocamlformat"];
formats = { formats = {
ocamlformat = { ocamlformat = {
package = pkgs.ocamlPackages.ocamlformat; command = getExe pkgs.ocamlPackages.ocamlformat;
}; };
}; };
in { in {
@ -49,38 +71,33 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "OCaml LSP support (ocaml-lsp)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "OCaml LSP support" // {default = config.vim.lsp.enable;};
server = mkOption {
description = "OCaml LSP server to user"; servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.ocaml.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
}; description = "OCaml LSP server to use";
package = mkOption {
description = "OCaml language server package, or the command to run as a list of strings";
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
format = { format = {
enable = mkEnableOption "OCaml formatting support (ocamlformat)" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "OCaml formatting support (ocamlformat)" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "OCaml formatter to use"; type = deprecatedSingleOrListOf "vim.language.ocaml.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "OCaml formatter to use";
package = mkOption {
description = "OCaml formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.ocaml-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {
@ -91,9 +108,14 @@ in {
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.ocaml = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.ocaml = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -7,26 +7,28 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) either listOf package str enum; inherit (lib.meta) getExe;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.attrsets) mapListToAttrs;
defaultServer = "ols"; defaultServers = ["ols"];
servers = { servers = {
ols = { ols = {
package = pkgs.ols; enable = true;
lspConfig = '' cmd = [(getExe pkgs.ols)];
lspconfig.ols.setup { filetypes = ["odin"];
capabilities = capabilities, root_dir =
on_attach = default_on_attach, mkLuaInline
cmd = ${ /*
if isList cfg.lsp.package lua
then expToLua cfg.lsp.package */
else "{'${cfg.lsp.package}/bin/ols'}" ''
} function(bufnr, on_dir)
} local fname = vim.api.nvim_buf_get_name(bufnr)
''; on_dir(util.root_pattern('ols.json', '.git', '*.odin')(fname))
end'';
}; };
}; };
@ -43,17 +45,11 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Odin LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Odin LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.odin.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
description = "Odin LSP server to use"; description = "Odin LSP server to use";
}; };
package = mkOption {
description = "Ols package, or the command to run as a list of strings";
type = either package (listOf str);
default = pkgs.ols;
};
}; };
}; };
@ -64,8 +60,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.odin-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -8,81 +8,60 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) enum either listOf package str; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.lua) expToLua; inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.php; cfg = config.vim.languages.php;
defaultServer = "phpactor"; defaultServers = ["phpactor"];
servers = { servers = {
phpactor = { phpactor = {
package = pkgs.phpactor; enable = true;
lspConfig = '' cmd = [(getExe pkgs.phpactor) "language-server"];
lspconfig.phpactor.setup{ filetypes = ["php"];
capabilities = capabilities, root_markers = [".git" "composer.json" ".phpactor.json" ".phpactor.yml"];
on_attach = default_on_attach, workspace_required = true;
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''
{
"${getExe cfg.lsp.package}",
"language-server"
},
''
}
}
'';
}; };
phan = { phan = {
package = pkgs.php81Packages.phan; enable = true;
lspConfig = '' cmd = [
lspconfig.phan.setup{ (getExe pkgs.php81Packages.phan)
capabilities = capabilities, "-m"
on_attach = default_on_attach, "json"
cmd = ${ "--no-color"
if isList cfg.lsp.package "--no-progress-bar"
then expToLua cfg.lsp.package "-x"
else '' "-u"
{ "-S"
"${getExe cfg.lsp.package}", "--language-server-on-stdin"
"-m", "--allow-polyfill-parser"
"json", ];
"--no-color", filetypes = ["php"];
"--no-progress-bar", root_dir =
"-x", mkLuaInline
"-u", /*
"-S", lua
"--language-server-on-stdin", */
"--allow-polyfill-parser" ''
}, function(bufnr, on_dir)
'' local fname = vim.api.nvim_buf_get_name(bufnr)
} local cwd = assert(vim.uv.cwd())
} local root = vim.fs.root(fname, { 'composer.json', '.git' })
'';
-- prefer cwd if root is a descendant
on_dir(root and vim.fs.relpath(cwd, root) and cwd)
end
'';
}; };
intelephense = { intelephense = {
package = pkgs.intelephense; enable = true;
lspConfig = '' cmd = [(getExe pkgs.intelephense) "--stdio"];
lspconfig.intelephense.setup{ filetypes = ["php"];
capabilities = capabilities, root_markers = ["composer.json" ".git"];
on_attach = default_on_attach,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''
{
"${getExe cfg.lsp.package}",
"--stdio"
},
''
}
}
'';
}; };
}; };
in { in {
@ -97,17 +76,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "PHP LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "PHP LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.php.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "PHP LSP server to use"; description = "PHP LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "PHP LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
}; };
@ -117,11 +89,14 @@ in {
vim.treesitter.enable = true; vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package]; vim.treesitter.grammars = [cfg.treesitter.package];
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig = { vim.lsp.servers =
enable = true; mapListToAttrs (n: {
sources.php-lsp = servers.${cfg.lsp.server}.lspConfig; name = n;
}; value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -6,88 +6,152 @@
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.meta) getExe; inherit (lib.lists) flatten;
inherit (lib.meta) getExe getExe';
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum package bool;
inherit (lib.types) enum either listOf package str bool; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) deprecatedSingleOrListOf;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryBefore;
inherit (lib.trivial) warn;
cfg = config.vim.languages.python; cfg = config.vim.languages.python;
defaultServer = "basedpyright"; defaultServers = ["basedpyright"];
servers = { servers = {
pyright = { pyright = {
package = pkgs.pyright; enable = true;
lspConfig = '' cmd = [(getExe' pkgs.pyright "pyright-langserver") "--stdio"];
lspconfig.pyright.setup{ filetypes = ["python"];
capabilities = capabilities; root_markers = [
on_attach = default_on_attach; "pyproject.toml"
cmd = ${ "setup.py"
if isList cfg.lsp.package "setup.cfg"
then expToLua cfg.lsp.package "requirements.txt"
else ''{"${cfg.lsp.package}/bin/pyright-langserver", "--stdio"}'' "Pipfile"
} "pyrightconfig.json"
} ".git"
];
settings = {
python = {
analysis = {
autoSearchPaths = true;
useLibraryCodeForTypes = true;
diagnosticMode = "openFilesOnly";
};
};
};
on_attach = mkLuaInline ''
function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightOrganizeImports', function()
local params = {
command = 'pyright.organizeimports',
arguments = { vim.uri_from_bufnr(bufnr) },
}
-- Using client.request() directly because "pyright.organizeimports" is private
-- (not advertised via capabilities), which client:exec_cmd() refuses to call.
-- https://github.com/neovim/neovim/blob/c333d64663d3b6e0dd9aa440e433d346af4a3d81/runtime/lua/vim/lsp/client.lua#L1024-L1030
client.request('workspace/executeCommand', params, nil, bufnr)
end, {
desc = 'Organize Imports',
})
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', set_python_path, {
desc = 'Reconfigure basedpyright with the provided python path',
nargs = 1,
complete = 'file',
})
end
''; '';
}; };
basedpyright = { basedpyright = {
package = pkgs.basedpyright; enable = true;
lspConfig = '' cmd = [(getExe' pkgs.basedpyright "basedpyright-langserver") "--stdio"];
lspconfig.basedpyright.setup{ filetypes = ["python"];
capabilities = capabilities; root_markers = [
on_attach = default_on_attach; "pyproject.toml"
cmd = ${ "setup.py"
if isList cfg.lsp.package "setup.cfg"
then expToLua cfg.lsp.package "requirements.txt"
else ''{"${cfg.lsp.package}/bin/basedpyright-langserver", "--stdio"}'' "Pipfile"
} "pyrightconfig.json"
} ".git"
];
settings = {
basedpyright = {
analysis = {
autoSearchPaths = true;
useLibraryCodeForTypes = true;
diagnosticMode = "openFilesOnly";
};
};
};
on_attach = mkLuaInline ''
function(client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightOrganizeImports', function()
local params = {
command = 'basedpyright.organizeimports',
arguments = { vim.uri_from_bufnr(bufnr) },
}
-- Using client.request() directly because "basedpyright.organizeimports" is private
-- (not advertised via capabilities), which client:exec_cmd() refuses to call.
-- https://github.com/neovim/neovim/blob/c333d64663d3b6e0dd9aa440e433d346af4a3d81/runtime/lua/vim/lsp/client.lua#L1024-L1030
client.request('workspace/executeCommand', params, nil, bufnr)
end, {
desc = 'Organize Imports',
})
vim.api.nvim_buf_create_user_command(bufnr, 'LspPyrightSetPythonPath', set_python_path, {
desc = 'Reconfigure basedpyright with the provided python path',
nargs = 1,
complete = 'file',
})
end
''; '';
}; };
python-lsp-server = { python-lsp-server = {
package = pkgs.python3Packages.python-lsp-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.python3Packages.python-lsp-server)];
lspconfig.pylsp.setup{ filetypes = ["python"];
capabilities = capabilities; root_markers = [
on_attach = default_on_attach; "pyproject.toml"
cmd = ${ "setup.py"
if isList cfg.lsp.package "setup.cfg"
then expToLua cfg.lsp.package "requirements.txt"
else ''{"${cfg.lsp.package}/bin/pylsp"}'' "Pipfile"
} ".git"
} ];
'';
}; };
}; };
defaultFormat = "black"; defaultFormat = ["black"];
formats = { formats = {
black = { black = {
package = pkgs.black; command = getExe pkgs.black;
}; };
isort = { isort = {
package = pkgs.isort; command = getExe pkgs.isort;
}; };
black-and-isort = { # dummy option for backwards compat
package = pkgs.writeShellApplication { black-and-isort = {};
name = "black";
runtimeInputs = [pkgs.black pkgs.isort];
text = ''
black --quiet - "$@" | isort --profile black -
'';
};
};
ruff = { ruff = {
command = getExe pkgs.ruff;
args = ["format" "-"];
};
ruff-check = {
package = pkgs.writeShellApplication { package = pkgs.writeShellApplication {
name = "ruff"; name = "ruff-check";
runtimeInputs = [pkgs.ruff]; runtimeInputs = [pkgs.ruff];
text = '' text = ''
ruff format - ruff check --fix --exit-zero -
''; '';
}; };
}; };
@ -171,17 +235,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Python LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Python LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.python.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Python LSP server to use"; description = "Python LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "python LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -189,30 +246,24 @@ in {
enable = mkEnableOption "Python formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Python formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Python formatter to use"; type = deprecatedSingleOrListOf "vim.language.python.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Python formatters to use";
package = mkOption {
description = "Python formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
# TODO this implementation is very bare bones, I don't know enough python to implement everything # TODO this implementation is very bare bones, I don't know enough python to implement everything
dap = { dap = {
enable = mkOption { enable = mkOption {
description = "Enable Python Debug Adapter";
type = bool; type = bool;
default = config.vim.languages.enableDAP; default = config.vim.languages.enableDAP;
description = "Enable Python Debug Adapter";
}; };
debugger = mkOption { debugger = mkOption {
description = "Python debugger to use";
type = enum (attrNames debuggers); type = enum (attrNames debuggers);
default = defaultDebugger; default = defaultDebugger;
description = "Python debugger to use";
}; };
package = mkOption { package = mkOption {
@ -234,26 +285,59 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.luaConfigRC.python-util =
vim.lsp.lspconfig.sources.python-lsp = servers.${cfg.lsp.server}.lspConfig; entryBefore ["lsp-servers"]
/*
lua
*/
''
local function set_python_path(server_name, command)
local path = command.args
local clients = vim.lsp.get_clients {
bufnr = vim.api.nvim_get_current_buf(),
name = server_name,
}
for _, client in ipairs(clients) do
if client.settings then
client.settings.python = vim.tbl_deep_extend('force', client.settings.python or {}, { pythonPath = path })
else
client.config.settings = vim.tbl_deep_extend('force', client.config.settings, { python = { pythonPath = path } })
end
client:notify('workspace/didChangeConfiguration', { settings = nil })
end
end
'';
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = let
names = flatten (map (type:
if type == "black-and-isort"
then
warn ''
vim.languages.python.format.type: "black-and-isort" is deprecated,
use `["black" "isort"]` instead.
'' ["black" "isort"]
else type)
cfg.format.type);
in {
enable = true; enable = true;
# HACK: I'm planning to remove these soon so I just took the easiest way out setupOpts = {
setupOpts.formatters_by_ft.python = formatters_by_ft.python = names;
if cfg.format.type == "black-and-isort" formatters =
then ["black"] mapListToAttrs (name: {
else [cfg.format.type]; inherit name;
setupOpts.formatters = value = formats.${name};
if (cfg.format.type == "black-and-isort") })
then { names;
black.command = "${cfg.format.package}/bin/black"; };
}
else {
${cfg.format.type}.command = getExe cfg.format.package;
};
}; };
}) })

View file

@ -0,0 +1,95 @@
{
config,
pkgs,
lib,
...
}: let
inherit (builtins) attrNames;
inherit (lib.meta) getExe';
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.qml;
qmlPackage = pkgs.kdePackages.qtdeclarative;
defaultServers = ["qmlls"];
servers = {
qmlls = {
cmd = [(getExe' qmlPackage "qmlls")];
filetypes = ["qml" "qmljs"];
rootmarkers = [".git"];
};
};
defaultFormat = ["qmlformat"];
formats = {
qmlformat = {
command = "${qmlPackage}/bin/qmlformat";
args = ["-i" "$FILENAME"];
stdin = false;
};
};
in {
options.vim.languages.qml = {
enable = mkEnableOption "QML language support";
treesitter = {
enable = mkEnableOption "QML treesitter support" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "qmljs";
};
lsp = {
enable = mkEnableOption "QML LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.qml.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "QML LSP server to use";
};
};
format = {
enable = mkEnableOption "QML formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption {
type = deprecatedSingleOrListOf "vim.language.qml.format.type" (enum (attrNames formats));
default = defaultFormat;
description = "QML formatter to use";
};
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter = {
enable = true;
grammars = [cfg.treesitter.package];
};
})
(mkIf cfg.lsp.enable {
vim.lsp.servers =
mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
})
(mkIf (cfg.format.enable && !cfg.lsp.enable) {
vim.formatter.conform-nvim = {
enable = true;
setupOpts = {
formatters_by_ft.qml = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
};
})
]);
}

View file

@ -5,12 +5,13 @@
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption literalExpression; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum;
inherit (lib.types) enum either listOf package str; inherit (lib.meta) getExe;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.r; cfg = config.vim.languages.r;
@ -18,54 +19,44 @@
packages = [pkgs.rPackages.languageserver]; packages = [pkgs.rPackages.languageserver];
}; };
defaultFormat = "format_r"; defaultFormat = ["format_r"];
formats = { formats = {
styler = { styler = {
package = pkgs.rWrapper.override { command = let
packages = [pkgs.rPackages.styler]; pkg = pkgs.rWrapper.override {packages = [pkgs.rPackages.styler];};
}; in "${pkg}/bin/R";
config = {
command = "${cfg.format.package}/bin/R";
};
}; };
format_r = { format_r = {
package = pkgs.rWrapper.override { command = let
packages = [pkgs.rPackages.formatR]; pkg = pkgs.rWrapper.override {
}; packages = [pkgs.rPackages.formatR];
config = { };
command = "${cfg.format.package}/bin/R"; in "${pkg}/bin/R";
stdin = true; stdin = true;
args = [ args = [
"--slave" "--slave"
"--no-restore" "--no-restore"
"--no-save" "--no-save"
"-s" "-s"
"-e" "-e"
''formatR::tidy_source(source="stdin")'' ''formatR::tidy_source(source="stdin")''
]; ];
# TODO: range_args seem to be possible # TODO: range_args seem to be possible
# https://github.com/nvimtools/none-ls.nvim/blob/main/lua/null-ls/builtins/formatting/format_r.lua # https://github.com/nvimtools/none-ls.nvim/blob/main/lua/null-ls/builtins/formatting/format_r.lua
};
}; };
}; };
defaultServer = "r_language_server"; defaultServers = ["r_language_server"];
servers = { servers = {
r_language_server = { r_language_server = {
package = pkgs.writeShellScriptBin "r_lsp" '' enable = true;
${r-with-languageserver}/bin/R --slave -e "languageserver::run()" cmd = [(getExe r-with-languageserver) "--no-echo" "-e" "languageserver::run()"];
''; filetypes = ["r" "rmd" "quarto"];
lspConfig = '' root_dir = mkLuaInline ''
lspconfig.r_language_server.setup{ function(bufnr, on_dir)
capabilities = capabilities; on_dir(vim.fs.root(bufnr, '.git') or vim.uv.os_homedir())
on_attach = default_on_attach; end
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${lib.getExe cfg.lsp.package}"}''
}
}
''; '';
}; };
}; };
@ -81,17 +72,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "R LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "R LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.r.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "R LSP server to use"; description = "R LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "R LSP server package, or the command to run as a list of strings";
example = literalExpression "[ (lib.getExe pkgs.jdt-language-server) \"-data\" \"~/.cache/jdtls/workspace\" ]";
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -99,16 +83,10 @@ in {
enable = mkEnableOption "R formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "R formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.r.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "R formatter to use"; description = "R formatter to use";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "R formatter package";
};
}; };
}; };
@ -121,14 +99,25 @@ in {
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.r = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = formats.${cfg.format.type}.config; formatters_by_ft.r = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
}; };
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.r-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -8,55 +8,51 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.types) mkGrammarOption diagnostics deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.types) enum;
inherit (lib.lists) isList; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.types) either listOf package str enum;
cfg = config.vim.languages.ruby; cfg = config.vim.languages.ruby;
defaultServer = "rubyserver"; defaultServers = ["solargraph"];
servers = { servers = {
rubyserver = { ruby_lsp = {
package = pkgs.rubyPackages.solargraph; enable = true;
lspConfig = '' cmd = [(getExe pkgs.ruby-lsp)];
lspconfig.solargraph.setup { filetypes = ["ruby" "eruby"];
capabilities = capabilities, root_markers = ["Gemfile" ".git"];
on_attach = attach_keymaps, init_options = {
flags = { formatter = "auto";
debounce_text_changes = 150, };
},
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{ "${cfg.lsp.package}/bin/solargraph", "stdio" }''
}
}
'';
}; };
rubylsp = {
package = pkgs.ruby-lsp; solargraph = {
lspConfig = '' enable = true;
lspconfig.ruby_lsp.setup { cmd = [(getExe pkgs.rubyPackages.solargraph) "stdio"];
capabilities = capabilities, filetypes = ["ruby"];
on_attach = default_on_attach, root_markers = ["Gemfile" ".git"];
cmd = ${ settings = {
if isList cfg.lsp.package solargraph = {
then expToLua cfg.lsp.package diagnostics = true;
else ''{ "${cfg.lsp.package}/bin/ruby-lsp" }'' };
} };
}
''; flags = {
debounce_text_changes = 150;
};
init_options = {
formatting = true;
};
}; };
}; };
# testing # testing
defaultFormat = "rubocop"; defaultFormat = ["rubocop"];
formats = { formats = {
rubocop = { rubocop = {
# TODO: is this right? command = getExe pkgs.rubyPackages.rubocop;
package = pkgs.rubyPackages.rubocop;
}; };
}; };
@ -64,7 +60,6 @@
diagnosticsProviders = { diagnosticsProviders = {
rubocop = { rubocop = {
package = pkgs.rubyPackages.rubocop; package = pkgs.rubyPackages.rubocop;
config.command = getExe cfg.format.package;
}; };
}; };
in { in {
@ -79,33 +74,21 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Ruby LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Ruby LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.ruby.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
description = "Ruby LSP server to use"; description = "Ruby LSP server to use";
}; };
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
description = "Ruby LSP server package, or the command to run as a list of strings";
};
}; };
format = { format = {
enable = mkEnableOption "Ruby formatter support" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Ruby formatter support" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.ruby.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
description = "Ruby formatter to use"; description = "Ruby formatter to use";
}; };
package = mkOption {
type = package;
default = formats.${cfg.format.type}.package;
description = "Ruby formatter package";
};
}; };
extraDiagnostics = { extraDiagnostics = {
@ -128,16 +111,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.ruby-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.ruby = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.ruby = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -4,24 +4,24 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.options) mkOption mkEnableOption literalMD; inherit (lib.options) mkOption mkEnableOption literalMD;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.trivial) boolToString;
inherit (lib.lists) isList; inherit (lib.lists) isList;
inherit (lib.types) bool package str listOf either enum; inherit (lib.attrsets) attrNames;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.types) bool package str listOf either enum int;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.lua) expToLua toLuaObject;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption deprecatedSingleOrListOf;
inherit (lib.nvim.dag) entryAfter entryAnywhere; inherit (lib.nvim.dag) entryAfter entryAnywhere;
cfg = config.vim.languages.rust; cfg = config.vim.languages.rust;
defaultFormat = "rustfmt"; defaultFormat = ["rustfmt"];
formats = { formats = {
rustfmt = { rustfmt = {
package = pkgs.rustfmt; command = getExe pkgs.rustfmt;
}; };
}; };
in { in {
@ -33,15 +33,6 @@ in {
package = mkGrammarOption pkgs "rust"; package = mkGrammarOption pkgs "rust";
}; };
crates = {
enable = mkEnableOption "crates-nvim, tools for managing dependencies";
codeActions = mkOption {
description = "Enable code actions through null-ls";
type = bool;
default = true;
};
};
lsp = { lsp = {
enable = mkEnableOption "Rust LSP support (rust-analyzer with extra tools)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Rust LSP support (rust-analyzer with extra tools)" // {default = config.vim.lsp.enable;};
package = mkOption { package = mkOption {
@ -79,15 +70,9 @@ in {
type = mkOption { type = mkOption {
description = "Rust formatter to use"; description = "Rust formatter to use";
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.rust.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
}; };
package = mkOption {
description = "Rust formatter package";
type = package;
default = formats.${cfg.format.type}.package;
};
}; };
dap = { dap = {
@ -103,25 +88,39 @@ in {
default = pkgs.lldb; default = pkgs.lldb;
}; };
}; };
extensions = {
crates-nvim = {
enable = mkEnableOption "crates.io dependency management [crates-nvim]";
setupOpts = mkPluginSetupOption "crates-nvim" {
lsp = {
enabled = mkEnableOption "crates.nvim's in-process language server" // {default = cfg.extensions.crates-nvim.enable;};
actions = mkEnableOption "actions for crates-nvim's in-process language server" // {default = cfg.extensions.crates-nvim.enable;};
completion = mkEnableOption "completion for crates-nvim's in-process language server" // {default = cfg.extensions.crates-nvim.enable;};
hover = mkEnableOption "hover actions for crates-nvim's in-process language server" // {default = cfg.extensions.crates-nvim.enable;};
};
completion = {
crates = {
enabled = mkEnableOption "completion for crates-nvim's in-process language server" // {default = cfg.extensions.crates-nvim.enable;};
max_results = mkOption {
description = "The maximum number of search results to display";
type = int;
default = 8;
};
min_chars = mkOption {
description = "The minimum number of characters to type before completions begin appearing";
type = int;
default = 3;
};
};
};
};
};
};
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.crates.enable {
vim = {
startPlugins = ["crates-nvim"];
lsp.null-ls.enable = mkIf cfg.crates.codeActions true;
autocomplete.nvim-cmp.sources = {crates = "[Crates]";};
pluginRC.rust-crates = entryAnywhere ''
require('crates').setup {
null_ls = {
enabled = ${boolToString cfg.crates.codeActions},
name = "crates.nvim",
}
}
'';
};
})
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {
vim.treesitter.enable = true; vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package]; vim.treesitter.grammars = [cfg.treesitter.package];
@ -130,9 +129,14 @@ in {
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.rust = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.rust = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })
@ -140,7 +144,6 @@ in {
(mkIf (cfg.lsp.enable || cfg.dap.enable) { (mkIf (cfg.lsp.enable || cfg.dap.enable) {
vim = { vim = {
startPlugins = ["rustaceanvim"]; startPlugins = ["rustaceanvim"];
pluginRC.rustaceanvim = entryAfter ["lsp-setup"] '' pluginRC.rustaceanvim = entryAfter ["lsp-setup"] ''
vim.g.rustaceanvim = { vim.g.rustaceanvim = {
${optionalString cfg.lsp.enable '' ${optionalString cfg.lsp.enable ''
@ -199,5 +202,16 @@ in {
''; '';
}; };
}) })
(mkIf cfg.extensions.crates-nvim.enable {
vim = mkMerge [
{
startPlugins = ["crates-nvim"];
pluginRC.rust-crates = entryAnywhere ''
require("crates").setup(${toLuaObject cfg.extensions.crates-nvim.setupOpts})
'';
}
];
})
]); ]);
} }

View file

@ -8,43 +8,36 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) enum package str;
inherit (lib.types) enum either listOf package str; inherit (lib.nvim.types) diagnostics deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) diagnostics; inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.sql; cfg = config.vim.languages.sql;
sqlfluffDefault = pkgs.sqlfluff; sqlfluffDefault = pkgs.sqlfluff;
defaultServer = "sqls"; defaultServers = ["sqls"];
servers = { servers = {
sqls = { sqls = {
package = pkgs.sqls; enable = true;
lspConfig = '' cmd = [(getExe pkgs.sqls)];
lspconfig.sqls.setup { filetypes = ["sql" "mysql"];
on_attach = function(client) root_markers = ["config.yml"];
client.server_capabilities.execute_command = true settings = {};
on_attach_keymaps(client, bufnr) on_attach = mkLuaInline ''
require'sqls'.setup{} function(client, bufnr)
end, client.server_capabilities.execute_command = true
cmd = ${ require'sqls'.setup{}
if isList cfg.lsp.package end
then expToLua cfg.lsp.package
else ''{ "${cfg.lsp.package}/bin/sqls", "-config", string.format("%s/config.yml", vim.fn.getcwd()) }''
}
}
''; '';
}; };
}; };
defaultFormat = "sqlfluff"; defaultFormat = ["sqlfluff"];
formats = { formats = {
sqlfluff = { sqlfluff = {
package = sqlfluffDefault; command = getExe sqlfluffDefault;
config = { append_args = ["--dialect=${cfg.dialect}"];
command = getExe cfg.format.package;
append_args = ["--dialect=${cfg.dialect}"];
};
}; };
}; };
@ -63,35 +56,28 @@ in {
enable = mkEnableOption "SQL language support"; enable = mkEnableOption "SQL language support";
dialect = mkOption { dialect = mkOption {
description = "SQL dialect for sqlfluff (if used)";
type = str; type = str;
default = "ansi"; default = "ansi";
description = "SQL dialect for sqlfluff (if used)";
}; };
treesitter = { treesitter = {
enable = mkEnableOption "SQL treesitter" // {default = config.vim.languages.enableTreesitter;}; enable = mkEnableOption "SQL treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkOption { package = mkOption {
description = "SQL treesitter grammar to use";
type = package; type = package;
default = pkgs.vimPlugins.nvim-treesitter.builtGrammars.sql; default = pkgs.vimPlugins.nvim-treesitter.builtGrammars.sql;
description = "SQL treesitter grammar to use";
}; };
}; };
lsp = { lsp = {
enable = mkEnableOption "SQL LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "SQL LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.sql.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "SQL LSP server to use"; description = "SQL LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "SQL LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -99,15 +85,9 @@ in {
enable = mkEnableOption "SQL formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "SQL formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "SQL formatter to use"; type = deprecatedSingleOrListOf "vim.language.sql.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "SQL formatter to use";
package = mkOption {
description = "SQL formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -132,18 +112,27 @@ in {
vim = { vim = {
startPlugins = ["sqls-nvim"]; startPlugins = ["sqls-nvim"];
lsp.lspconfig = { lsp.servers =
enable = true; mapListToAttrs (n: {
sources.sql-lsp = servers.${cfg.lsp.server}.lspConfig; name = n;
}; value = servers.${n};
})
cfg.lsp.servers;
}; };
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.sql = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = formats.${cfg.format.type}.config; formatters_by_ft.sql = cfg.format.type;
formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
};
}; };
}) })

View file

@ -1,4 +1,5 @@
{ {
self,
config, config,
pkgs, pkgs,
lib, lib,
@ -7,41 +8,65 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum package coercedTo;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption diagnostics deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption diagnostics; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.svelte; cfg = config.vim.languages.svelte;
defaultServer = "svelte"; defaultServers = ["svelte"];
servers = { servers = {
svelte = { svelte = {
package = pkgs.svelte-language-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.svelte-language-server) "--stdio"];
lspconfig.svelte.setup { filetypes = ["svelte"];
capabilities = capabilities; root_dir = mkLuaInline ''
on_attach = attach_keymaps, function(bufnr, on_dir)
cmd = ${ local root_files = { 'package.json', '.git' }
if isList cfg.lsp.package local fname = vim.api.nvim_buf_get_name(bufnr)
then expToLua cfg.lsp.package -- Svelte LSP only supports file:// schema. https://github.com/sveltejs/language-tools/issues/2777
else ''{"${cfg.lsp.package}/bin/svelteserver", "--stdio"}'' if vim.uv.fs_stat(fname) ~= nil then
} on_dir(vim.fs.dirname(vim.fs.find(root_files, { path = fname, upward = true })[1]))
} end
end
'';
on_attach = mkLuaInline ''
function(client, bufnr)
vim.api.nvim_create_autocmd('BufWritePost', {
pattern = { '*.js', '*.ts' },
group = vim.api.nvim_create_augroup('svelte_js_ts_file_watch', {}),
callback = function(ctx)
-- internal API to sync changes that have not yet been saved to the file system
client:notify('$/onDidChangeTsOrJsFile', { uri = ctx.match })
end,
})
vim.api.nvim_buf_create_user_command(bufnr, 'LspMigrateToSvelte5', function()
client:exec_cmd({
command = 'migrate_to_svelte_5',
arguments = { vim.uri_from_bufnr(bufnr) },
})
end, { desc = 'Migrate Component to Svelte 5 Syntax' })
end
''; '';
}; };
}; };
# TODO: specify packages defaultFormat = ["prettier"];
defaultFormat = "prettier"; formats = let
formats = { prettierPlugin = self.packages.${pkgs.stdenv.system}.prettier-plugin-svelte;
prettierPluginPath = "${prettierPlugin}/lib/node_modules/prettier-plugin-svelte/plugin.js";
in {
prettier = { prettier = {
package = pkgs.prettier; command = getExe pkgs.nodePackages.prettier;
options.ft_parsers.svelte = "svelte";
prepend_args = ["--plugin=${prettierPluginPath}"];
}; };
biome = { biome = {
package = pkgs.biome; command = getExe pkgs.biome;
}; };
}; };
@ -65,6 +90,15 @@
}; };
}; };
}; };
formatType =
deprecatedSingleOrListOf
"vim.languages.svelte.format.type"
(coercedTo (enum ["prettierd"]) (_:
lib.warn
"vim.languages.svelte.format.type: prettierd is deprecated, use prettier instead"
"prettier")
(enum (attrNames formats)));
in { in {
options.vim.languages.svelte = { options.vim.languages.svelte = {
enable = mkEnableOption "Svelte language support"; enable = mkEnableOption "Svelte language support";
@ -78,17 +112,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Svelte LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Svelte LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.svelte.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Svelte LSP server to use"; description = "Svelte LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Svelte LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -96,15 +123,9 @@ in {
enable = mkEnableOption "Svelte formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Svelte formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Svelte formatter to use"; type = formatType;
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Svelte formatter to use";
package = mkOption {
description = "Svelte formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -126,16 +147,25 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.svelte-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.svelte = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.svelte = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })

View file

@ -7,26 +7,142 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.types) deprecatedSingleOrListOf;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.tailwind; cfg = config.vim.languages.tailwind;
defaultServer = "tailwindcss-language-server"; defaultServers = ["tailwindcss"];
servers = { servers = {
tailwindcss-language-server = { tailwindcss = {
package = pkgs.tailwindcss-language-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.tailwindcss-language-server) "--stdio"];
lspconfig.tailwindcss.setup { filetypes = [
capabilities = capabilities; # html
on_attach = default_on_attach; "aspnetcorerazor"
cmd = ${ "astro"
if isList cfg.lsp.package "astro-markdown"
then expToLua cfg.lsp.package "blade"
else ''{"${cfg.lsp.package}/bin/tailwindcss-language-server", "--stdio"}'' "clojure"
} "django-html"
} "htmldjango"
"edge"
"eelixir"
"elixir"
"ejs"
"erb"
"eruby"
"gohtml"
"gohtmltmpl"
"haml"
"handlebars"
"hbs"
"html"
"htmlangular"
"html-eex"
"heex"
"jade"
"leaf"
"liquid"
"markdown"
"mdx"
"mustache"
"njk"
"nunjucks"
"php"
"razor"
"slim"
"twig"
# css
"css"
"less"
"postcss"
"sass"
"scss"
"stylus"
"sugarss"
# js
"javascript"
"javascriptreact"
"reason"
"rescript"
"typescript"
"typescriptreact"
# mixed
"vue"
"svelte"
"templ"
];
settings = {
tailwindCSS = {
validate = true;
lint = {
cssConflict = "warning";
invalidApply = "error";
invalidScreen = "error";
invalidVariant = "error";
invalidConfigPath = "error";
invalidTailwindDirective = "error";
recommendedVariantOrder = "warning";
};
classAttributes = [
"class"
"className"
"class:list"
"classList"
"ngClass"
];
includeLanguages = {
eelixir = "html-eex";
elixir = "phoenix-heex";
eruby = "erb";
heex = "phoenix-heex";
htmlangular = "html";
templ = "html";
};
};
};
before_init = mkLuaInline ''
function(_, config)
if not config.settings then
config.settings = {}
end
if not config.settings.editor then
config.settings.editor = {}
end
if not config.settings.editor.tabSize then
config.settings.editor.tabSize = vim.lsp.util.get_effective_tabstop()
end
end
'';
workspace_required = true;
root_dir = mkLuaInline ''
function(bufnr, on_dir)
local root_files = {
-- Generic
'tailwind.config.js',
'tailwind.config.cjs',
'tailwind.config.mjs',
'tailwind.config.ts',
'postcss.config.js',
'postcss.config.cjs',
'postcss.config.mjs',
'postcss.config.ts',
-- Django
'theme/static_src/tailwind.config.js',
'theme/static_src/tailwind.config.cjs',
'theme/static_src/tailwind.config.mjs',
'theme/static_src/tailwind.config.ts',
'theme/static_src/postcss.config.js',
}
local fname = vim.api.nvim_buf_get_name(bufnr)
root_files = util.insert_package_json(root_files, 'tailwindcss', fname)
root_files = util.root_markers_with_field(root_files, { 'mix.lock', 'Gemfile.lock' }, 'tailwind', fname)
on_dir(vim.fs.dirname(vim.fs.find(root_files, { path = fname, upward = true })[1]))
end
''; '';
}; };
}; };
@ -37,25 +153,22 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Tailwindcss LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Tailwindcss LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.tailwind.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Tailwindcss LSP server to use"; description = "Tailwindcss LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Tailwindcss LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server " - data " " ~/.cache/jdtls/workspace "]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
}; };
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.tailwindcss-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -4,12 +4,25 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.types) package; inherit (lib.meta) getExe;
inherit (lib.types) enum listOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.terraform; cfg = config.vim.languages.terraform;
defaultServers = ["terraformls"];
servers = {
terraformls = {
enable = true;
cmd = [(getExe pkgs.terraform-ls) "serve"];
filetypes = ["terraform" "terraform-vars"];
root_markers = [".terraform" ".git"];
};
};
in { in {
options.vim.languages.terraform = { options.vim.languages.terraform = {
enable = mkEnableOption "Terraform/HCL support"; enable = mkEnableOption "Terraform/HCL support";
@ -22,10 +35,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Terraform LSP support (terraform-ls)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Terraform LSP support (terraform-ls)" // {default = config.vim.lsp.enable;};
package = mkOption { servers = mkOption {
description = "terraform-ls package"; type = listOf (enum (attrNames servers));
type = package; default = defaultServers;
default = pkgs.terraform-ls; description = "Terraform LSP server to use";
}; };
}; };
}; };
@ -36,14 +49,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.terraform-ls = '' mapListToAttrs (n: {
lspconfig.terraformls.setup { name = n;
capabilities = capabilities, value = servers.${n};
on_attach=default_on_attach, })
cmd = {"${cfg.lsp.package}/bin/terraform-ls", "serve"}, cfg.lsp.servers;
}
'';
}) })
]); ]);
} }

View file

@ -4,86 +4,187 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames elem;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str bool; inherit (lib.types) enum package bool;
inherit (lib.nvim.lua) expToLua toLuaObject; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.types) mkGrammarOption diagnostics mkPluginSetupOption; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.types) mkGrammarOption diagnostics mkPluginSetupOption deprecatedSingleOrListOf;
inherit (lib.nvim.dag) entryAnywhere entryBefore;
cfg = config.vim.languages.ts; cfg = config.vim.languages.ts;
defaultServer = "ts_ls"; defaultServers = ["ts_ls"];
servers = { servers = let
ts_ls = { ts_ls = {
package = pkgs.typescript-language-server; cmd = [(getExe pkgs.typescript-language-server) "--stdio"];
lspConfig = '' init_options = {hostInfo = "neovim";};
lspconfig.ts_ls.setup { filetypes = [
capabilities = capabilities, "javascript"
on_attach = function(client, bufnr) "javascriptreact"
attach_keymaps(client, bufnr); "javascript.jsx"
client.server_capabilities.documentFormattingProvider = false; "typescript"
end, "typescriptreact"
cmd = ${ "typescript.tsx"
if isList cfg.lsp.package ];
then expToLua cfg.lsp.package root_markers = ["tsconfig.json" "jsconfig.json" "package.json" ".git"];
else ''{"${cfg.lsp.package}/bin/typescript-language-server", "--stdio"}'' handlers = {
} # handle rename request for certain code actions like extracting functions / types
} "_typescript.rename" = mkLuaInline ''
function(_, result, ctx)
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
vim.lsp.util.show_document({
uri = result.textDocument.uri,
range = {
start = result.position,
['end'] = result.position,
},
}, client.offset_encoding)
vim.lsp.buf.rename()
return vim.NIL
end
'';
};
on_attach = mkLuaInline ''
function(client, bufnr)
-- ts_ls provides `source.*` code actions that apply to the whole file. These only appear in
-- `vim.lsp.buf.code_action()` if specified in `context.only`.
vim.api.nvim_buf_create_user_command(0, 'LspTypescriptSourceAction', function()
local source_actions = vim.tbl_filter(function(action)
return vim.startswith(action, 'source.')
end, client.server_capabilities.codeActionProvider.codeActionKinds)
vim.lsp.buf.code_action({
context = {
only = source_actions,
},
})
end, {})
end
''; '';
}; };
in {
denols = { inherit ts_ls;
package = pkgs.deno;
lspConfig = ''
vim.g.markdown_fenced_languages = { "ts=typescript" }
lspconfig.denols.setup {
capabilities = capabilities;
on_attach = attach_keymaps,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/deno", "lsp"}''
}
}
'';
};
# Here for backwards compatibility. Still consider tsserver a valid # Here for backwards compatibility. Still consider tsserver a valid
# configuration in the enum, but assert if it's set to *properly* # configuration in the enum, but assert if it's set to *properly*
# redirect the user to the correct server. # redirect the user to the correct server.
tsserver = { tsserver = ts_ls;
package = pkgs.typescript-language-server;
lspConfig = '' denols = {
lspconfig.ts_ls.setup { cmd = [(getExe pkgs.deno) "lsp"];
capabilities = capabilities; cmd_env = {NO_COLOR = true;};
on_attach = attach_keymaps, filetypes = [
cmd = ${ "javascript"
if isList cfg.lsp.package "javascriptreact"
then expToLua cfg.lsp.package "javascript.jsx"
else ''{"${cfg.lsp.package}/bin/typescript-language-server", "--stdio"}'' "typescript"
} "typescriptreact"
} "typescript.tsx"
];
root_markers = ["deno.json" "deno.jsonc" ".git"];
settings = {
deno = {
enable = true;
suggest = {
imports = {
hosts = {
"https://deno.land" = true;
};
};
};
};
};
handlers = {
"textDocument/definition" = mkLuaInline "nvf_denols_handler";
"textDocument/typeDefinition" = mkLuaInline "nvf_denols_handler";
"textDocument/references" = mkLuaInline "nvf_denols_handler";
};
on_attach = mkLuaInline ''
function(client, bufnr)
vim.api.nvim_buf_create_user_command(0, 'LspDenolsCache', function()
client:exec_cmd({
command = 'deno.cache',
arguments = { {}, vim.uri_from_bufnr(bufnr) },
}, { bufnr = bufnr }, function(err, _result, ctx)
if err then
local uri = ctx.params.arguments[2]
vim.api.nvim_err_writeln('cache command failed for ' .. vim.uri_to_fname(uri))
end
end)
end, {
desc = 'Cache a module and all of its dependencies.',
})
end
''; '';
}; };
}; };
denols_handlers = ''
local function nvf_denols_virtual_text_document_handler(uri, res, client)
if not res then
return nil
end
local lines = vim.split(res.result, '\n')
local bufnr = vim.uri_to_bufnr(uri)
local current_buf = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
if #current_buf ~= 0 then
return nil
end
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
vim.api.nvim_set_option_value('readonly', true, { buf = bufnr })
vim.api.nvim_set_option_value('modified', false, { buf = bufnr })
vim.api.nvim_set_option_value('modifiable', false, { buf = bufnr })
vim.lsp.buf_attach_client(bufnr, client.id)
end
local function nvf_denols_virtual_text_document(uri, client)
local params = {
textDocument = {
uri = uri,
},
}
local result = client.request_sync('deno/virtualTextDocument', params)
nvf_denols_virtual_text_document_handler(uri, result, client)
end
local function nvf_denols_handler(err, result, ctx, config)
if not result or vim.tbl_isempty(result) then
return nil
end
local client = vim.lsp.get_client_by_id(ctx.client_id)
for _, res in pairs(result) do
local uri = res.uri or res.targetUri
if uri:match '^deno:' then
nvf_denols_virtual_text_document(uri, client)
res['uri'] = uri
res['targetUri'] = uri
end
end
vim.lsp.handlers[ctx.method](err, result, ctx, config)
end
'';
# TODO: specify packages # TODO: specify packages
defaultFormat = "prettier"; defaultFormat = ["prettier"];
formats = { formats = {
prettier = { prettier = {
package = pkgs.prettier; command = getExe pkgs.prettier;
}; };
prettierd = { prettierd = {
package = pkgs.prettierd; command = getExe pkgs.prettierd;
}; };
biome = { biome = {
package = pkgs.biome; command = getExe pkgs.biome;
}; };
}; };
@ -115,24 +216,18 @@ in {
treesitter = { treesitter = {
enable = mkEnableOption "Typescript/Javascript treesitter" // {default = config.vim.languages.enableTreesitter;}; enable = mkEnableOption "Typescript/Javascript treesitter" // {default = config.vim.languages.enableTreesitter;};
tsPackage = mkGrammarOption pkgs "tsx"; tsPackage = mkGrammarOption pkgs "typescript";
tsxPackage = mkGrammarOption pkgs "tsx";
jsPackage = mkGrammarOption pkgs "javascript"; jsPackage = mkGrammarOption pkgs "javascript";
}; };
lsp = { lsp = {
enable = mkEnableOption "Typescript/Javascript LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Typescript/Javascript LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.ts.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Typescript/Javascript LSP server to use"; description = "Typescript/Javascript LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Typescript/Javascript LSP server package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -141,15 +236,9 @@ in {
type = mkOption { type = mkOption {
description = "Typescript/Javascript formatter to use"; description = "Typescript/Javascript formatter to use";
type = enum (attrNames formats); type = deprecatedSingleOrListOf "vim.language.ts.format.type" (enum (attrNames formats));
default = defaultFormat; default = defaultFormat;
}; };
package = mkOption {
description = "Typescript/Javascript formatter package";
type = package;
default = formats.${cfg.format.type}.package;
};
}; };
extraDiagnostics = { extraDiagnostics = {
@ -186,24 +275,43 @@ in {
config = mkIf cfg.enable (mkMerge [ config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable { (mkIf cfg.treesitter.enable {
vim.treesitter.enable = true; vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.tsPackage cfg.treesitter.jsPackage]; vim.treesitter.grammars = [
cfg.treesitter.tsPackage
cfg.treesitter.tsxPackage
cfg.treesitter.jsPackage
];
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.ts-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (name: {
inherit name;
value = servers.${name};
})
cfg.lsp.servers;
})
(mkIf (cfg.lsp.enable && elem "denols" cfg.lsp.servers) {
vim.globals.markdown_fenced_languages = ["ts=typescript"];
vim.luaConfigRC.denols_handlers = entryBefore ["lsp-servers"] denols_handlers;
}) })
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts = { setupOpts = {
formatters_by_ft.typescript = [cfg.format.type]; formatters_by_ft = {
# .tsx files typescript = cfg.format.type;
formatters_by_ft.typescriptreact = [cfg.format.type]; javascript = cfg.format.type;
formatters.${cfg.format.type} = { # .tsx/.jsx files
command = getExe cfg.format.package; typescriptreact = cfg.format.type;
}; };
setupOpts.formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })
@ -234,7 +342,7 @@ in {
{ {
assertions = [ assertions = [
{ {
assertion = cfg.lsp.enable -> cfg.lsp.server != "tsserver"; assertion = cfg.lsp.enable -> !(elem "tsserver" cfg.lsp.servers);
message = '' message = ''
As of a recent lspconfig update, the `tsserver` configuration has been renamed As of a recent lspconfig update, the `tsserver` configuration has been renamed
to `ts_ls` to match upstream behaviour of `lspconfig`, and the name `tsserver` to `ts_ls` to match upstream behaviour of `lspconfig`, and the name `tsserver`

View file

@ -4,64 +4,99 @@
lib, lib,
... ...
}: let }: let
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.types) nullOr enum attrsOf listOf package str bool int;
inherit (lib.types) nullOr enum either attrsOf listOf package str bool int;
inherit (lib.attrsets) attrNames; inherit (lib.attrsets) attrNames;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.nvim.binds) mkMappingOption mkKeymap; inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua toLuaObject;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.binds) mkKeymap mkMappingOption;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.typst; cfg = config.vim.languages.typst;
defaultServer = "tinymist"; defaultServers = ["tinymist"];
servers = { servers = {
typst-lsp = { typst_lsp = {
package = pkgs.typst-lsp; enable = true;
lspConfig = '' cmd = [(getExe pkgs.typst-lsp)];
lspconfig.typst_lsp.setup { filetypes = ["typst"];
capabilities = capabilities, root_markers = [".git"];
on_attach = function(client, bufnr) on_attach = mkLuaInline ''
-- Disable semantic tokens as a workaround for a semantic token error when using non-english characters function(client, bufnr)
client.server_capabilities.semanticTokensProvider = nil -- Disable semantic tokens as a workaround for a semantic token error when using non-english characters
end, client.server_capabilities.semanticTokensProvider = nil
cmd = ${ end
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else ''{"${cfg.lsp.package}/bin/typst-lsp"}''
},
}
''; '';
}; };
tinymist = { tinymist = {
package = pkgs.tinymist; enable = true;
lspConfig = '' cmd = [(getExe pkgs.tinymist)];
lspconfig.tinymist.setup { filetypes = ["typst"];
capabilities = capabilities, root_markers = [".git"];
single_file_support = true, on_attach = mkLuaInline ''
on_attach = function(client, bufnr) function(client, bufnr)
-- Disable semantic tokens as a workaround for a semantic token error when using non-english characters local function create_tinymist_command(command_name, client, bufnr)
client.server_capabilities.semanticTokensProvider = nil local export_type = command_name:match 'tinymist%.export(%w+)'
end, local info_type = command_name:match 'tinymist%.(%w+)'
cmd = ${ if info_type and info_type:match '^get' then
if isList cfg.lsp.package info_type = info_type:gsub('^get', 'Get')
then expToLua cfg.lsp.package end
else ''{"${cfg.lsp.package}/bin/tinymist"}'' local cmd_display = export_type or info_type
}, local function run_tinymist_command()
} local arguments = { vim.api.nvim_buf_get_name(bufnr) }
local title_str = export_type and ('Export ' .. cmd_display) or cmd_display
local function handler(err, res)
if err then
return vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
end
vim.notify(export_type and res or vim.inspect(res), vim.log.levels.INFO)
end
if vim.fn.has 'nvim-0.11' == 1 then
return client:exec_cmd({
title = title_str,
command = command_name,
arguments = arguments,
}, { bufnr = bufnr }, handler)
else
return vim.notify('Tinymist commands require Neovim 0.11+', vim.log.levels.WARN)
end
end
local cmd_name = export_type and ('LspTinymistExport' .. cmd_display) or ('LspTinymist' .. cmd_display)
local cmd_desc = export_type and ('Export to ' .. cmd_display) or ('Get ' .. cmd_display)
return run_tinymist_command, cmd_name, cmd_desc
end
for _, command in ipairs {
'tinymist.exportSvg',
'tinymist.exportPng',
'tinymist.exportPdf',
'tinymist.exportMarkdown',
'tinymist.exportText',
'tinymist.exportQuery',
'tinymist.exportAnsiHighlight',
'tinymist.getServerInfo',
'tinymist.getDocumentTrace',
'tinymist.getWorkspaceLabels',
'tinymist.getDocumentMetrics',
} do
local cmd_func, cmd_name, cmd_desc = create_tinymist_command(command, client, bufnr)
vim.api.nvim_buf_create_user_command(bufnr, cmd_name, cmd_func, { nargs = 0, desc = cmd_desc })
end
end
''; '';
}; };
}; };
defaultFormat = "typstyle"; defaultFormat = ["typstyle"];
formats = { formats = {
# https://github.com/Enter-tainer/typstyle # https://github.com/Enter-tainer/typstyle
typstyle = { typstyle = {
package = pkgs.typstyle; command = getExe pkgs.typstyle;
}; };
}; };
in { in {
@ -76,17 +111,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Typst LSP support (typst-lsp)" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Typst LSP support (typst-lsp)" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.typst.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Typst LSP server to use"; description = "Typst LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "typst-lsp package, or the command to run as a list of strings";
example = ''[lib.getExe pkgs.jdt-language-server "-data" "~/.cache/jdtls/workspace"]'';
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
@ -94,15 +122,9 @@ in {
enable = mkEnableOption "Typst document formatting" // {default = config.vim.languages.enableFormat;}; enable = mkEnableOption "Typst document formatting" // {default = config.vim.languages.enableFormat;};
type = mkOption { type = mkOption {
description = "Typst formatter to use"; type = deprecatedSingleOrListOf "vim.language.typst.format.type" (enum (attrNames formats));
type = enum (attrNames formats);
default = defaultFormat; default = defaultFormat;
}; description = "Typst formatter to use";
package = mkOption {
description = "Typst formatter package";
type = package;
default = formats.${cfg.format.type}.package;
}; };
}; };
@ -129,7 +151,7 @@ in {
dependencies_bin = mkOption { dependencies_bin = mkOption {
type = attrsOf str; type = attrsOf str;
default = { default = {
"tinymist" = getExe servers.tinymist.package; "tinymist" = getExe pkgs.tinymist;
"websocat" = getExe pkgs.websocat; "websocat" = getExe pkgs.websocat;
}; };
@ -210,16 +232,25 @@ in {
(mkIf cfg.format.enable { (mkIf cfg.format.enable {
vim.formatter.conform-nvim = { vim.formatter.conform-nvim = {
enable = true; enable = true;
setupOpts.formatters_by_ft.typst = [cfg.format.type]; setupOpts = {
setupOpts.formatters.${cfg.format.type} = { formatters_by_ft.typst = cfg.format.type;
command = getExe cfg.format.package; formatters =
mapListToAttrs (name: {
inherit name;
value = formats.${name};
})
cfg.format.type;
}; };
}; };
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.typst-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
# Extensions # Extensions

View file

@ -7,36 +7,58 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.generators) mkLuaInline;
cfg = config.vim.languages.vala; cfg = config.vim.languages.vala;
defaultServer = "vala_ls"; defaultServers = ["vala_ls"];
servers = { servers = {
vala_ls = { vala_ls = {
package = pkgs.symlinkJoin { enable = true;
name = "vala-language-server-wrapper"; cmd = [
paths = [pkgs.vala-language-server]; (getExe (pkgs.symlinkJoin {
buildInputs = [pkgs.makeBinaryWrapper]; name = "vala-language-server-wrapper";
postBuild = '' paths = [pkgs.vala-language-server];
wrapProgram $out/bin/vala-language-server \ meta.mainProgram = "vala-language-server-wrapper";
--prefix PATH : ${pkgs.uncrustify}/bin buildInputs = [pkgs.makeBinaryWrapper];
''; postBuild = ''
}; wrapProgram $out/bin/vala-language-server \
internalFormatter = true; --prefix PATH : ${pkgs.uncrustify}/bin
lspConfig = '' '';
lspconfig.vala_ls.setup { }))
capabilities = capabilities; ];
on_attach = default_on_attach; filetypes = ["vala" "genie"];
cmd = ${ root_dir = mkLuaInline ''
if isList cfg.lsp.package function(bufnr, on_dir)
then expToLua cfg.lsp.package local meson_matcher = function(path)
else ''{"${cfg.lsp.package}/bin/vala-language-server"}'' local pattern = 'meson.build'
}, local f = vim.fn.glob(table.concat({ path, pattern }, '/'))
} if f == ''' then
return nil
end
for line in io.lines(f) do
-- skip meson comments
if not line:match '^%s*#.*' then
local str = line:gsub('%s+', ''')
if str ~= ''' then
if str:match '^project%(' then
return path
else
break
end
end
end
end
end
local fname = vim.api.nvim_buf_get_name(bufnr)
local root = vim.iter(vim.fs.parents(fname)):find(meson_matcher)
on_dir(root or vim.fs.dirname(vim.fs.find('.git', { path = fname, upward = true })[1]))
end
''; '';
}; };
}; };
@ -51,16 +73,10 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Vala LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Vala LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = deprecatedSingleOrListOf "vim.language.vala.lsp.servers" (enum (attrNames servers));
default = defaultServers;
description = "Vala LSP server to use"; description = "Vala LSP server to use";
type = enum (attrNames servers);
default = defaultServer;
};
package = mkOption {
description = "Vala LSP server package, or the command to run as a list of strings";
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
}; };
}; };
}; };
@ -72,8 +88,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.vala_ls = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -5,31 +5,23 @@
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.lists) isList;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.options) literalExpression mkEnableOption mkOption; inherit (lib.types) enum;
inherit (lib.types) either enum listOf package str; inherit (lib.meta) getExe;
inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.wgsl; cfg = config.vim.languages.wgsl;
defaultServer = "wgsl-analyzer"; defaultServers = ["wgsl-analyzer"];
servers = { servers = {
wgsl-analyzer = { wgsl-analyzer = {
package = pkgs.wgsl-analyzer; enable = true;
internalFormatter = true; cmd = [(getExe pkgs.wgsl-analyzer)];
lspConfig = '' filetypes = ["wgsl"];
lspconfig.wgsl_analyzer.setup { root_markers = [".git"];
capabilities = capabilities, settings = {};
on_attach = default_on_attach,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else "{'${cfg.lsp.package}/bin/wgsl-analyzer'}"
}
}
'';
}; };
}; };
in { in {
@ -44,18 +36,11 @@ in {
lsp = { lsp = {
enable = mkEnableOption "WGSL LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "WGSL LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.wgsl.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
description = "WGSL LSP server to use"; description = "WGSL LSP server to use";
}; };
package = mkOption {
description = "wgsl-analyzer package, or the command to run as a list of strings";
example = literalExpression "[(lib.getExe pkgs.wgsl-analyzer)]";
type = either package (listOf str);
default = pkgs.wgsl-analyzer;
};
}; };
}; };
@ -68,12 +53,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim = { vim.lsp.servers =
lsp.lspconfig = { mapListToAttrs (n: {
enable = true; name = n;
sources.wgsl_analyzer = servers.${cfg.lsp.server}.lspConfig; value = servers.${n};
}; })
}; cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -5,43 +5,45 @@
... ...
}: let }: let
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.generators) mkLuaInline;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) isList; inherit (lib.meta) getExe;
inherit (lib.types) enum either listOf package str; inherit (lib.types) enum;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.yaml; cfg = config.vim.languages.yaml;
onAttach = on_attach =
if config.vim.languages.helm.lsp.enable if config.vim.languages.helm.lsp.enable && config.vim.languages.helm.enable
then '' then
on_attach = function(client, bufnr) mkLuaInline ''
local filetype = vim.bo[bufnr].filetype function(client, bufnr)
if filetype == "helm" then local filetype = vim.bo[bufnr].filetype
client.stop() if filetype == "helm" then
client.stop()
end
end end
end'' ''
else "on_attach = default_on_attach"; else null;
defaultServer = "yaml-language-server"; defaultServers = ["yaml-language-server"];
servers = { servers = {
yaml-language-server = { yaml-language-server = {
package = pkgs.yaml-language-server; enable = true;
lspConfig = '' cmd = [(getExe pkgs.yaml-language-server) "--stdio"];
filetypes = ["yaml" "yaml.docker-compose" "yaml.gitlab" "yaml.helm-values"];
root_markers = [".git"];
lspconfig.yamlls.setup { inherit on_attach;
capabilities = capabilities, # -- https://github.com/redhat-developer/vscode-redhat-telemetry#how-to-disable-telemetry-reporting
${onAttach}, settings = {
cmd = ${ redhat = {
if isList cfg.lsp.package telemetry = {
then expToLua cfg.lsp.package enabled = false;
else ''{"${cfg.lsp.package}/bin/yaml-language-server", "--stdio"}'' };
}, };
} };
'';
}; };
}; };
in { in {
@ -55,18 +57,11 @@ in {
}; };
lsp = { lsp = {
enable = mkEnableOption "YAML LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Yaml LSP support" // {default = config.vim.lsp.enable;};
servers = mkOption {
server = mkOption { type = deprecatedSingleOrListOf "vim.language.yaml.lsp.servers" (enum (attrNames servers));
type = enum (attrNames servers); default = defaultServers;
default = defaultServer; description = "Yaml LSP server to use";
description = "YAML LSP server to use";
};
package = mkOption {
type = either package (listOf str);
default = servers.${cfg.lsp.server}.package;
description = "YAML LSP server package";
}; };
}; };
}; };
@ -78,8 +73,12 @@ in {
}) })
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true; vim.lsp.servers =
vim.lsp.lspconfig.sources.yaml-lsp = servers.${cfg.lsp.server}.lspConfig; mapListToAttrs (n: {
name = n;
value = servers.${n};
})
cfg.lsp.servers;
}) })
]); ]);
} }

View file

@ -7,29 +7,21 @@
inherit (builtins) attrNames; inherit (builtins) attrNames;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.modules) mkIf mkMerge mkDefault; inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.lists) isList; inherit (lib.types) bool package enum;
inherit (lib.types) bool either listOf package str enum; inherit (lib.nvim.types) mkGrammarOption deprecatedSingleOrListOf;
inherit (lib.nvim.lua) expToLua; inherit (lib.meta) getExe;
inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.attrsets) mapListToAttrs;
cfg = config.vim.languages.zig; cfg = config.vim.languages.zig;
defaultServer = "zls"; defaultServers = ["zls"];
servers = { servers = {
zls = { zls = {
package = pkgs.zls; enable = true;
internalFormatter = true; cmd = [(getExe pkgs.zls)];
lspConfig = '' filetypes = ["zig" "zir"];
lspconfig.zls.setup { root_markers = ["zls.json" "build.zig" ".git"];
capabilities = capabilities, workspace_required = false;
on_attach = default_on_attach,
cmd = ${
if isList cfg.lsp.package
then expToLua cfg.lsp.package
else "{'${cfg.lsp.package}/bin/zls'}"
}
}
'';
}; };
}; };
@ -74,17 +66,11 @@ in {
lsp = { lsp = {
enable = mkEnableOption "Zig LSP support" // {default = config.vim.lsp.enable;}; enable = mkEnableOption "Zig LSP support" // {default = config.vim.lsp.enable;};
server = mkOption { servers = mkOption {
type = enum (attrNames servers); type = deprecatedSingleOrListOf "vim.language.zig.lsp.servers" (enum (attrNames servers));
default = defaultServer; default = defaultServers;
description = "Zig LSP server to use"; description = "Zig LSP server to use";
}; };
package = mkOption {
description = "ZLS package, or the command to run as a list of strings";
type = either package (listOf str);
default = pkgs.zls;
};
}; };
dap = { dap = {
@ -118,10 +104,12 @@ in {
(mkIf cfg.lsp.enable { (mkIf cfg.lsp.enable {
vim = { vim = {
lsp.lspconfig = { lsp.servers =
enable = true; mapListToAttrs (n: {
sources.zig-lsp = servers.${cfg.lsp.server}.lspConfig; name = n;
}; value = servers.${n};
})
cfg.lsp.servers;
# nvf handles autosaving already # nvf handles autosaving already
globals.zig_fmt_autosave = mkDefault 0; globals.zig_fmt_autosave = mkDefault 0;

View file

@ -1,7 +1,7 @@
{ {
config, config,
lib, lib,
pkgs, options,
... ...
}: let }: let
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;
@ -10,20 +10,21 @@
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.trivial) boolToString; inherit (lib.trivial) boolToString;
inherit (lib.nvim.binds) addDescriptionsToMappings; inherit (lib.nvim.binds) addDescriptionsToMappings;
inherit (lib.nvim.dag) entryBefore;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp; cfg = config.vim.lsp;
usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable; usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
usingBlinkCmp = config.vim.autocomplete.blink-cmp.enable; usingBlinkCmp = config.vim.autocomplete.blink-cmp.enable;
self = import ./module.nix {inherit config lib pkgs;};
conformCfg = config.vim.formatter.conform-nvim; conformCfg = config.vim.formatter.conform-nvim;
conformFormatOnSave = conformCfg.enable && conformCfg.setupOpts.format_on_save != null; conformFormatOnSave = conformCfg.enable && conformCfg.setupOpts.format_on_save != null;
augroup = "nvf_lsp"; augroup = "nvf_lsp";
mappingDefinitions = self.options.vim.lsp.mappings; mappingDefinitions = options.vim.lsp.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
mkBinding = binding: action: mkBinding = binding: action:
if binding.value != null if binding.value != null
then "vim.keymap.set('n', '${binding.value}', ${action}, {buffer=bufnr, noremap=true, silent=true, desc='${binding.description}'})" then "vim.keymap.set('n', ${toLuaObject binding.value}, ${action}, {buffer=bufnr, noremap=true, silent=true, desc=${toLuaObject binding.description}})"
else ""; else "";
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
@ -35,20 +36,26 @@ in {
augroups = [{name = augroup;}]; augroups = [{name = augroup;}];
autocmds = autocmds =
(optional cfg.inlayHints.enable { [
group = augroup; {
event = ["LspAttach"]; group = augroup;
desc = "LSP on-attach enable inlay hints autocmd"; event = ["LspAttach"];
callback = mkLuaInline '' desc = "LSP on-attach add keybinds, enable inlay hints, and other plugin integrations";
function(event) callback = mkLuaInline ''
local bufnr = event.buf function(event)
local client = vim.lsp.get_client_by_id(event.data.client_id) local bufnr = event.buf
if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint) then local client = vim.lsp.get_client_by_id(event.data.client_id)
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr }) default_on_attach(client, bufnr)
${optionalString cfg.inlayHints.enable ''
if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint) then
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled({ bufnr = bufnr }), { bufnr = bufnr })
end
''}
end end
end '';
''; }
}) ]
++ (optional (!conformFormatOnSave) { ++ (optional (!conformFormatOnSave) {
group = augroup; group = augroup;
event = ["BufWritePre"]; event = ["BufWritePre"];
@ -87,7 +94,7 @@ in {
''; '';
}); });
pluginRC.lsp-setup = '' pluginRC.lsp-setup = entryBefore ["autocmds"] ''
vim.g.formatsave = ${boolToString cfg.formatOnSave}; vim.g.formatsave = ${boolToString cfg.formatOnSave};
local attach_keymaps = function(client, bufnr) local attach_keymaps = function(client, bufnr)

View file

@ -7,6 +7,7 @@
./lspconfig ./lspconfig
./lspsaga ./lspsaga
./null-ls ./null-ls
./harper-ls
# lsp plugins # lsp plugins
./lspsaga ./lspsaga

View file

@ -0,0 +1,19 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.meta) getExe;
cfg = config.vim.lsp;
in {
config = mkIf (cfg.enable && cfg.harper-ls.enable) {
vim.lsp.servers.harper-ls = {
root_markers = [".git"];
cmd = [(getExe pkgs.harper) "--stdio"];
settings = {harper-ls = cfg.harper-ls.settings;};
};
};
}

View file

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

View file

@ -0,0 +1,35 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) anything attrsOf;
in {
options.vim.lsp.harper-ls = {
enable = mkEnableOption "Harper grammar checking LSP";
settings = mkOption {
type = attrsOf anything;
default = {};
example = {
userDictPath = "";
workspaceDictPath = "";
fileDictPath = "";
linters = {
BoringWords = true;
PossessiveNoun = true;
SentenceCapitalization = false;
SpellCheck = false;
};
codeActions = {
ForceStable = false;
};
markdown = {
IgnoreLinkTitle = false;
};
diagnosticSeverity = "hint";
isolateEnglish = false;
dialect = "American";
maxFileLength = 120000;
ignoredLintsPath = {};
};
description = "Settings to pass to harper-ls";
};
};
}

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -9,9 +10,8 @@
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp.nvim-docs-view; cfg = config.vim.lsp.nvim-docs-view;
self = import ./nvim-docs-view.nix {inherit lib;};
mappingDefinitions = self.options.vim.lsp.nvim-docs-view.mappings; mappingDefinitions = options.vim.lsp.nvim-docs-view.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -10,8 +11,7 @@
cfg = config.vim.lsp; cfg = config.vim.lsp;
self = import ./otter.nix {inherit lib;}; mappingDefinitions = options.vim.lsp.otter-nvim.mappings;
mappingDefinitions = self.options.vim.lsp.otter-nvim.mappings;
mappings = addDescriptionsToMappings cfg.otter-nvim.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.otter-nvim.mappings mappingDefinitions;
in { in {
config = mkIf (cfg.enable && cfg.otter-nvim.enable) { config = mkIf (cfg.enable && cfg.otter-nvim.enable) {

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -9,9 +10,7 @@
cfg = config.vim.minimap.codewindow; cfg = config.vim.minimap.codewindow;
self = import ./codewindow.nix {inherit lib;}; mappingDefinitions = options.vim.minimap.codewindow.mappings;
mappingDefinitions = self.options.vim.minimap.codewindow.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -5,9 +5,9 @@
... ...
}: let }: let
inherit (lib.modules) mkRenamedOptionModule; inherit (lib.modules) mkRenamedOptionModule;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption mkPackageOption;
inherit (lib.types) str listOf; inherit (lib.types) str listOf;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption; inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
imports = [ imports = [
(mkRenamedOptionModule ["vim" "notes" "orgmode" "orgAgendaFiles"] ["vim" "notes" "orgmode" "setupOpts" "org_agenda_files"]) (mkRenamedOptionModule ["vim" "notes" "orgmode" "orgAgendaFiles"] ["vim" "notes" "orgmode" "setupOpts" "org_agenda_files"])
@ -33,7 +33,9 @@ in {
treesitter = { treesitter = {
enable = mkEnableOption "Orgmode treesitter" // {default = config.vim.languages.enableTreesitter;}; enable = mkEnableOption "Orgmode treesitter" // {default = config.vim.languages.enableTreesitter;};
orgPackage = mkGrammarOption pkgs "org"; orgPackage = mkPackageOption pkgs ["org-nvim treesitter"] {
default = ["tree-sitter-grammars" "tree-sitter-org-nvim"];
};
}; };
}; };
} }

View file

@ -1,7 +1,7 @@
{ {
pkgs,
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkMerge mkIf; inherit (lib.modules) mkMerge mkIf;
@ -9,8 +9,7 @@
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.notes.todo-comments; cfg = config.vim.notes.todo-comments;
self = import ./todo-comments.nix {inherit pkgs lib;}; inherit (options.vim.notes.todo-comments) mappings;
inherit (self.options.vim.notes.todo-comments) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {

View file

@ -5,4 +5,5 @@
"oxocarbon" "oxocarbon"
"gruvbox" "gruvbox"
"nord" "nord"
"mellow"
] ]

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -9,8 +10,8 @@
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.tabline.nvimBufferline; cfg = config.vim.tabline.nvimBufferline;
self = import ./nvim-bufferline.nix {inherit config lib;};
inherit (self.options.vim.tabline.nvimBufferline) mappings; inherit (options.vim.tabline.nvimBufferline) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {

View file

@ -315,4 +315,13 @@ in {
styles = ["hard" "medium" "soft"]; styles = ["hard" "medium" "soft"];
}; };
mellow = {
setup = {transparent ? false, ...}: ''
-- Mellow configuration
vim.g.mellow_transparent = ${boolToString transparent}
vim.cmd.colorscheme("mellow")
'';
};
} }

View file

@ -1,7 +1,7 @@
{ {
config, config,
pkgs,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -12,8 +12,7 @@
cfg = config.vim.treesitter; cfg = config.vim.treesitter;
self = import ./treesitter.nix {inherit pkgs lib;}; mappingDefinitions = options.vim.treesitter.mappings;
mappingDefinitions = self.options.vim.treesitter.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -19,6 +19,7 @@
./oil-nvim ./oil-nvim
./outline ./outline
./preview ./preview
./qmk-nvim
./sleuth ./sleuth
./smart-splits ./smart-splits
./snacks-nvim ./snacks-nvim

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -9,9 +10,7 @@
cfg = config.vim.gestures.gesture-nvim; cfg = config.vim.gestures.gesture-nvim;
self = import ./gesture-nvim.nix {inherit lib;}; mappingDefinitions = options.vim.gestures.gesture-nvim.mappings;
mappingDefinitions = self.options.vim.gestures.gesture-nvim.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -14,7 +14,7 @@ in {
"flash-nvim" = { "flash-nvim" = {
package = "flash-nvim"; package = "flash-nvim";
setupModule = "flash"; setupModule = "flash";
setupOpts = cfg.setupOpts; inherit (cfg) setupOpts;
lazy = true; lazy = true;

View file

@ -1,6 +1,7 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
@ -9,9 +10,7 @@
cfg = config.vim.utility.motion.hop; cfg = config.vim.utility.motion.hop;
self = import ./hop.nix {inherit lib;}; mappingDefinitions = options.vim.utility.motion.hop.mappings;
mappingDefinitions = self.options.vim.utility.motion.hop.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {

View file

@ -3,18 +3,38 @@
lib, lib,
... ...
}: let }: let
inherit (lib.attrsets) optionalAttrs recursiveUpdate;
inherit (lib.lists) optionals;
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAfter entryAnywhere;
cfg = config.vim.utility.oil-nvim; cfg = config.vim.utility.oil-nvim;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = ["oil-nvim"]; startPlugins = ["oil-nvim"] ++ (optionals cfg.gitStatus.enable ["oil-git-status.nvim"]);
pluginRC.oil-nvim = entryAnywhere ''
require("oil").setup(${toLuaObject cfg.setupOpts}); pluginRC.oil-nvim = let
''; gitStatusDefaultOpts = {
# https://github.com/refractalize/oil-git-status.nvim?tab=readme-ov-file#configuration
win_options = {
signcolumn = "yes:2";
};
};
setupOpts =
recursiveUpdate
(optionalAttrs cfg.gitStatus.enable gitStatusDefaultOpts)
cfg.setupOpts;
in
entryAnywhere ''
require("oil").setup(${toLuaObject setupOpts});
'';
pluginRC.oil-git-status-nvim = mkIf cfg.gitStatus.enable (entryAfter ["oil-nvim"] ''
require("oil-git-status").setup(${toLuaObject cfg.gitStatus.setupOpts})
'');
}; };
}; };
} }

View file

@ -8,5 +8,13 @@ in {
''; '';
setupOpts = mkPluginSetupOption "oil-nvim" {}; setupOpts = mkPluginSetupOption "oil-nvim" {};
gitStatus = {
enable = mkEnableOption ''
Git status on [oil-nvim] directory listings
'';
setupOpts = mkPluginSetupOption "oil-git-status-nvim" {};
};
}; };
} }

View file

@ -2,6 +2,7 @@
pkgs, pkgs,
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
@ -9,10 +10,7 @@
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.utility.preview.glow; cfg = config.vim.utility.preview.glow;
self = import ./glow.nix { inherit (options.vim.utility.preview.glow) mappings;
inherit lib config pkgs;
};
inherit (self.options.vim.utility.preview.glow) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = ["glow-nvim"]; vim.startPlugins = ["glow-nvim"];

View file

@ -0,0 +1,36 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAfter;
cfg = config.vim.utility.qmk-nvim;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["qmk-nvim"];
pluginRC.qmk-nvim = entryAfter ["nvim-notify"] ''
require('qmk').setup(${toLuaObject cfg.setupOpts})
'';
};
assertions = [
{
assertion = cfg.setupOpts.variant == "qmk" && cfg.setupOpts.comment_preview.position != "inside";
message = "comment_preview.position can only be set to inside when using the qmk layoyt";
}
{
assertion = cfg.setupOpts.name != null;
message = "qmk-nvim requires 'vim.utility.qmk.setupOpts.name' to be set.";
}
{
assertion = cfg.setupOpts.layout != null;
message = "qmk-nvim requires 'vim.utility.qmk.setupOpts.layout' to be set.";
}
];
};
}

View file

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

View file

@ -0,0 +1,49 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) attrsOf nullOr enum lines str;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
options.vim.utility.qmk-nvim = {
enable = mkEnableOption "QMK and ZMK keymaps in nvim";
setupOpts = mkPluginSetupOption "qmk.nvim" {
name = mkOption {
type = nullOr str;
default = null;
description = "The name of the layout";
};
layout = mkOption {
type = nullOr lines;
default = null;
description = ''
The keyboard key layout
see <https://github.com/codethread/qmk.nvim?tab=readme-ov-file#Layout> for more details
'';
};
variant = mkOption {
type = enum ["qmk" "zmk"];
default = "qmk";
description = "Chooses the expected hardware target";
};
comment_preview = {
position = mkOption {
type = enum ["top" "bottom" "inside" "none"];
default = "top";
description = "Controls the position of the preview";
};
keymap_overrides = mkOption {
type = attrsOf str;
default = {};
description = ''
Key codes to text replacements
see <https://github.com/codethread/qmk.nvim/blob/main/lua/qmk/config/key_map.lua> for more details
'';
};
};
};
};
}

View file

@ -22,9 +22,7 @@
passthru.vimPlugin = false; passthru.vimPlugin = false;
}; };
# build a vim plugin with the given name and arguments # Build a Vim plugin with the given name and arguments.
# if the plugin is nvim-treesitter, warn the user to use buildTreesitterPlug
# instead
buildPlug = attrs: let buildPlug = attrs: let
pin = getPin attrs.pname; pin = getPin attrs.pname;
in in
@ -36,6 +34,7 @@
// attrs // attrs
); );
# Build a given Treesitter grammar.
buildTreesitterPlug = grammars: vimPlugins.nvim-treesitter.withPlugins (_: grammars); buildTreesitterPlug = grammars: vimPlugins.nvim-treesitter.withPlugins (_: grammars);
pluginBuilders = { pluginBuilders = {
@ -48,6 +47,9 @@
doCheck = false; doCheck = false;
}; };
# Get plugins built from source from self.packages
# If adding a new plugin to be built from source, it must also be inherited
# here.
inherit (inputs.self.packages.${pkgs.stdenv.system}) blink-cmp avante-nvim; inherit (inputs.self.packages.${pkgs.stdenv.system}) blink-cmp avante-nvim;
}; };
@ -71,29 +73,38 @@
# Wrap the user's desired (unwrapped) Neovim package with arguments that'll be used to # Wrap the user's desired (unwrapped) Neovim package with arguments that'll be used to
# generate a wrapped Neovim package. # generate a wrapped Neovim package.
neovim-wrapped = inputs.mnw.lib.wrap {inherit pkgs;} { neovim-wrapped = inputs.mnw.lib.wrap {inherit pkgs;} {
appName = "nvf";
neovim = config.vim.package; neovim = config.vim.package;
initLua = config.vim.builtLuaConfigRC;
luaFiles = config.vim.extraLuaFiles;
# Plugin configurations
plugins = { plugins = {
start = buildConfigPlugins config.vim.startPlugins; start = buildConfigPlugins config.vim.startPlugins;
opt = buildConfigPlugins config.vim.optPlugins; opt = buildConfigPlugins config.vim.optPlugins;
}; };
appName = "nvf";
extraBinPath = config.vim.extraPackages; # Providers for Neovim
initLua = config.vim.builtLuaConfigRC;
luaFiles = config.vim.extraLuaFiles;
providers = { providers = {
ruby.enable = config.vim.withRuby;
nodeJs.enable = config.vim.withNodeJs;
python3 = { python3 = {
enable = config.vim.withPython3; enable = config.vim.withPython3;
extraPackages = ps: map (flip builtins.getAttr ps) config.vim.python3Packages; extraPackages = ps: map (flip builtins.getAttr ps) config.vim.python3Packages;
}; };
ruby.enable = config.vim.withRuby;
nodeJs.enable = config.vim.withNodeJs;
}; };
# Aliases to link `nvim` to
aliases = lib.optional config.vim.viAlias "vi" ++ lib.optional config.vim.vimAlias "vim"; aliases = lib.optional config.vim.viAlias "vi" ++ lib.optional config.vim.vimAlias "vim";
# Additional packages or Lua packages to be made available to Neovim
extraBinPath = config.vim.extraPackages;
extraLuaPackages = ps: map (flip builtins.getAttr ps) config.vim.luaPackages; extraLuaPackages = ps: map (flip builtins.getAttr ps) config.vim.luaPackages;
}; };
# A store path representing the built Lua configuration.
dummyInit = pkgs.writeText "nvf-init.lua" config.vim.builtLuaConfigRC; dummyInit = pkgs.writeText "nvf-init.lua" config.vim.builtLuaConfigRC;
# Additional helper scripts for printing and displaying nvf configuration # Additional helper scripts for printing and displaying nvf configuration
# in your commandline. # in your commandline.
printConfig = pkgs.writers.writeDashBin "nvf-print-config" "cat ${dummyInit}"; printConfig = pkgs.writers.writeDashBin "nvf-print-config" "cat ${dummyInit}";
@ -106,10 +117,23 @@
paths = [neovim-wrapped printConfig printConfigPath]; paths = [neovim-wrapped printConfig printConfigPath];
postBuild = "echo Helpers added"; postBuild = "echo Helpers added";
# Allow evaluating config.vim, i.e., config.vim from the packages' passthru passthru = {
# attribute. For example, packages.x86_64-linux.neovim.passthru.neovimConfig # Allow evaluating config.vim, i.e., config.vim from the packages' passthru
# will return the configuration in full. # attribute. For example, packages.x86_64-linux.neovim.passthru.neovimConfig
passthru.neovimConfig = config.vim; # will return the configuration in full.
neovimConfig = config.vim;
# Also expose the helper scripts in passthru.
nvfPrintConfig = printConfig;
nvfPrintConfigPath = printConfigPath;
# In systems where we only have a package and no module, this can be used
# to access the built init.lua
initLua = dummyInit;
mnwConfig = neovim-wrapped.passthru.config;
mnwConfigDir = neovim-wrapped.passthru.configDir;
};
meta = meta =
neovim-wrapped.meta neovim-wrapped.meta

View file

@ -3,7 +3,7 @@
lib, lib,
... ...
}: let }: let
inherit (lib.options) mkOption mkEnableOption literalMD; inherit (lib.options) mkOption mkEnableOption literalMD literalExpression;
inherit (lib.types) package bool str listOf attrsOf; inherit (lib.types) package bool str listOf attrsOf;
inherit (lib.nvim.types) pluginsOpt extraPluginType; inherit (lib.nvim.types) pluginsOpt extraPluginType;
in { in {
@ -11,6 +11,7 @@ in {
package = mkOption { package = mkOption {
type = package; type = package;
default = pkgs.neovim-unwrapped; default = pkgs.neovim-unwrapped;
defaultText = literalExpression "pkgs.neovim-unwrapped";
description = '' description = ''
The neovim package to use for the wrapper. This The neovim package to use for the wrapper. This
corresponds to the package that will be wrapped corresponds to the package that will be wrapped
@ -27,21 +28,20 @@ in {
viAlias = mkOption { viAlias = mkOption {
type = bool; type = bool;
default = true; default = true;
example = false;
description = "Enable the `vi` alias for `nvim`"; description = "Enable the `vi` alias for `nvim`";
}; };
vimAlias = mkOption { vimAlias = mkOption {
type = bool; type = bool;
default = true; default = true;
example = false;
description = "Enable the `vim` alias for `nvim`"; description = "Enable the `vim` alias for `nvim`";
}; };
startPlugins = pluginsOpt { startPlugins = pluginsOpt {
default = ["plenary-nvim"]; default = ["plenary-nvim"];
example = '' example = literalExpression "[pkgs.vimPlugins.telescope-nvim]";
[pkgs.vimPlugins.telescope-nvim]
'';
description = '' description = ''
List of plugins to load on startup. This is used List of plugins to load on startup. This is used
internally to add plugins to Neovim's runtime. internally to add plugins to Neovim's runtime.
@ -54,9 +54,7 @@ in {
optPlugins = pluginsOpt { optPlugins = pluginsOpt {
default = []; default = [];
example = '' example = literalExpression "[pkgs.vimPlugins.vim-ghost]";
[pkgs.vimPlugins.vim-ghost]
'';
description = '' description = ''
List of plugins to optionally load on startup. List of plugins to optionally load on startup.
@ -108,7 +106,7 @@ in {
''; '';
}; };
# this defaults to `true` in the wrapper # This defaults to `true` in the wrapper
# and since we pass this value to the wrapper # and since we pass this value to the wrapper
# with an inherit, it should be `true` here as well # with an inherit, it should be `true` here as well
withRuby = withRuby =
@ -120,14 +118,14 @@ in {
}; };
withNodeJs = mkEnableOption '' withNodeJs = mkEnableOption ''
NodeJs support in the Neovim wrapper NodeJS support in the Neovim wrapper
''; '';
luaPackages = mkOption { luaPackages = mkOption {
type = listOf str; type = listOf str;
default = []; default = [];
example = ''["magick" "serpent"]''; example = ''["magick" "serpent"]'';
description = "List of lua packages to install"; description = "List of Lua packages to install";
}; };
withPython3 = mkEnableOption '' withPython3 = mkEnableOption ''
@ -144,7 +142,7 @@ in {
pluginOverrides = mkOption { pluginOverrides = mkOption {
type = attrsOf package; type = attrsOf package;
default = {}; default = {};
example = '' example = literalExpression ''
{ {
lazydev-nvim = pkgs.fetchFromGitHub { lazydev-nvim = pkgs.fetchFromGitHub {
owner = "folke"; owner = "folke";

View file

@ -1,7 +1,7 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkOption mkEnableOption; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) enum listOf submodule nullOr str bool int attrsOf anything either oneOf lines; inherit (lib.types) enum listOf submodule nullOr str bool int attrsOf anything either oneOf lines;
inherit (lib.nvim.types) pluginType; inherit (lib.nvim.types) pluginType luaInline;
inherit (lib.nvim.config) mkBool; inherit (lib.nvim.config) mkBool;
lznKeysSpec = submodule { lznKeysSpec = submodule {
@ -98,7 +98,7 @@
# lz.n options # lz.n options
enabled = mkOption { enabled = mkOption {
type = nullOr (either bool str); type = nullOr (either bool luaInline);
default = null; default = null;
description = "When false, or if the lua function returns false, this plugin will not be included in the spec"; description = "When false, or if the lua function returns false, this plugin will not be included in the spec";
}; };

View file

@ -964,6 +964,19 @@
"url": "https://github.com/OXY2DEV/markview.nvim/archive/de79a7626d54d7785436105ef72f37ee8fe8fa16.tar.gz", "url": "https://github.com/OXY2DEV/markview.nvim/archive/de79a7626d54d7785436105ef72f37ee8fe8fa16.tar.gz",
"hash": "032i6m9pld1zyhd7lq49dg4qh98w6vmmzqp2f46drhq0ds26hs4h" "hash": "032i6m9pld1zyhd7lq49dg4qh98w6vmmzqp2f46drhq0ds26hs4h"
}, },
"mellow": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "mellow-theme",
"repo": "mellow.nvim"
},
"branch": "main",
"submodules": false,
"revision": "5cd188489bcc7eb512f0a30581ad972070f8e5cd",
"url": "https://github.com/mellow-theme/mellow.nvim/archive/5cd188489bcc7eb512f0a30581ad972070f8e5cd.tar.gz",
"hash": "0hjfhwvvlc50rrxscg2lbkip7v5s13yaja0pckhhxfkbz17b5v83"
},
"mind-nvim": { "mind-nvim": {
"type": "Git", "type": "Git",
"repository": { "repository": {
@ -2091,6 +2104,19 @@
"url": "https://github.com/epwalsh/obsidian.nvim/archive/14e0427bef6c55da0d63f9a313fd9941be3a2479.tar.gz", "url": "https://github.com/epwalsh/obsidian.nvim/archive/14e0427bef6c55da0d63f9a313fd9941be3a2479.tar.gz",
"hash": "15ycmhn48ryaqzch6w3w6llq2qgmjx8xwkb9dn0075z60dybpflr" "hash": "15ycmhn48ryaqzch6w3w6llq2qgmjx8xwkb9dn0075z60dybpflr"
}, },
"oil-git-status.nvim": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "refractalize",
"repo": "oil-git-status.nvim"
},
"branch": "main",
"submodules": false,
"revision": "4b5cf53842c17a09420919e655a6a559da3112d7",
"url": "https://github.com/refractalize/oil-git-status.nvim/archive/4b5cf53842c17a09420919e655a6a559da3112d7.tar.gz",
"hash": "1jzw6lkvi9xxzqy8xz056xlb45byr1arklh87zmyf0nj9plm2nsp"
},
"oil-nvim": { "oil-nvim": {
"type": "Git", "type": "Git",
"repository": { "repository": {
@ -2208,6 +2234,38 @@
"url": "https://github.com/tris203/precognition.nvim/archive/2aae2687207029b3611a0e19a289f9e1c7efbe16.tar.gz", "url": "https://github.com/tris203/precognition.nvim/archive/2aae2687207029b3611a0e19a289f9e1c7efbe16.tar.gz",
"hash": "0b4yz5jvqd0li373067cs1n761vn9jxkhcvhsrvm9h1snqw1c6nk" "hash": "0b4yz5jvqd0li373067cs1n761vn9jxkhcvhsrvm9h1snqw1c6nk"
}, },
"prettier-plugin-astro": {
"type": "GitRelease",
"repository": {
"type": "GitHub",
"owner": "withastro",
"repo": "prettier-plugin-astro"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"submodules": false,
"version": "v0.14.1",
"revision": "57234893ca374c8e401cce1f931180d314e13eac",
"url": "https://api.github.com/repos/withastro/prettier-plugin-astro/tarball/v0.14.1",
"hash": "14ffwxggcnyc947pdxgsgz1v2q76m5xmybfxg8kyla4l7phg6qsw"
},
"prettier-plugin-svelte": {
"type": "GitRelease",
"repository": {
"type": "GitHub",
"owner": "sveltejs",
"repo": "prettier-plugin-svelte"
},
"pre_releases": false,
"version_upper_bound": null,
"release_prefix": null,
"submodules": false,
"version": "v3.3.2",
"revision": "76c04ebfdff4306842e8ab0cd96b1c53c7041dde",
"url": "https://api.github.com/repos/sveltejs/prettier-plugin-svelte/tarball/v3.3.2",
"hash": "0g6h5lvhyms6nvk83vkd3yi8rvsz2v5g6cw03fqsv2nj45s6cf7r"
},
"project-nvim": { "project-nvim": {
"type": "Git", "type": "Git",
"repository": { "repository": {
@ -2234,6 +2292,19 @@
"url": "https://github.com/kevinhwang91/promise-async/archive/119e8961014c9bfaf1487bf3c2a393d254f337e2.tar.gz", "url": "https://github.com/kevinhwang91/promise-async/archive/119e8961014c9bfaf1487bf3c2a393d254f337e2.tar.gz",
"hash": "0q4a0rmy09hka6zvydzjj2gcm2j5mlbrhbxfcdjj33ngpblkmqzm" "hash": "0q4a0rmy09hka6zvydzjj2gcm2j5mlbrhbxfcdjj33ngpblkmqzm"
}, },
"qmk-nvim": {
"type": "Git",
"repository": {
"type": "GitHub",
"owner": "codethread",
"repo": "qmk.nvim"
},
"branch": "main",
"submodules": false,
"revision": "3c804c1480991e4837514900b22b9358cfd64fa1",
"url": "https://github.com/codethread/qmk.nvim/archive/3c804c1480991e4837514900b22b9358cfd64fa1.tar.gz",
"hash": "03fsx6qsn8b36jp5m0fkdla6gkkzdv2j18y378y3cqpjclgq995a"
},
"rainbow-delimiters-nvim": { "rainbow-delimiters-nvim": {
"type": "Git", "type": "Git",
"repository": { "repository": {