This commit is contained in:
raf 2024-10-17 13:19:40 +00:00 committed by GitHub
commit 94f2791464
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
50 changed files with 1279 additions and 871 deletions

View file

@ -51,6 +51,7 @@ isMaximal: {
css.enable = isMaximal;
sql.enable = isMaximal;
java.enable = isMaximal;
kotlin.enable = isMaximal;
ts.enable = isMaximal;
svelte.enable = isMaximal;
go.enable = isMaximal;
@ -69,6 +70,7 @@ isMaximal: {
lsp.server = "clangd";
};
scala.enable = isMaximal;
rust = {
enable = isMaximal;
crates.enable = isMaximal;
@ -106,12 +108,10 @@ isMaximal: {
transparent = false;
};
autopairs.enable = true;
autopairs.nvim-autopairs.enable = true;
autocomplete = {
enable = true;
type = "nvim-cmp";
};
autocomplete.nvim-cmp.enable = true;
snippets.luasnip.enable = true;
filetree = {
nvimTree = {
@ -174,6 +174,7 @@ isMaximal: {
notes = {
obsidian.enable = false; # FIXME: neovim fails to build if obsidian is enabled
neorg.enable = false;
orgmode.enable = false;
mind-nvim.enable = isMaximal;
todo-comments.enable = true;

View file

@ -7,37 +7,26 @@ section contains a general overview to how you may utilize said functions.
## Custom Key Mappings Support for a Plugin {#sec-custom-key-mappings}
To set a mapping, you should define it in `vim.maps.<<mode>>`.
The available modes are:
- normal
- insert
- select
- visual
- terminal
- normalVisualOp
- visualOnly
- operator
- insertCommand
- lang
- command
To set a mapping, you should define it in `vim.keymaps`.
An example, simple keybinding, can look like this:
```nix
{
vim.maps.normal = {
"<leader>wq" = {
vim.keymaps = [
{
key = "<leader>wq";
mode = ["n"];
action = ":wq<CR>";
silent = true;
desc = "Save file and quit";
};
};
}
];
}
```
There are many settings available in the options. Please refer to the
[documentation](https://notashelf.github.io/nvf/options.html#opt-vim.maps.command._name_.action)
[documentation](https://notashelf.github.io/nvf/options.html#opt-vim.keymaps)
to see a list of them.
**nvf** provides a list of helper commands, so that you don't have to write the

View file

@ -26,6 +26,32 @@ making good use of its extensive Lua API. Additionally, Vimscript is slow and
brings unnecessary performance overhead while working with different
configuration formats.
### `vim.maps` rewrite {#sec-vim-maps-rewrite}
Instead of specifying map modes using submodules (eg.: `vim.maps.normal`), a new
`vim.keymaps` submodule with support for a `mode` option has been introduced. It
can be either a string, or a list of strings, where a string represents the
short-name of the map mode(s), that the mapping should be set for. See
`:help map-modes` for more information.
For example:
```nix
vim.maps.normal."<leader>m" = { ... };
```
has to be replaced by
```nix
vim.keymaps = [
{
key = "<leader>m";
mode = "n";
}
...
];
```
### `vim.lsp.nvimCodeActionMenu` removed in favor of `vim.ui.fastaction` {#sec-nvim-code-action-menu-deprecation}
The nvim-code-action-menu plugin has been archived and broken for a long time,
@ -37,6 +63,14 @@ Note that we are looking to add more alternatives in the future like
dressing.nvim and actions-preview.nvim, in case fastaction doesn't work for
everyone.
### `type` based modules removed {#sec-type-based-modules-removed}
As part of the autocompletion rewrite, modules that used to use a `type` option
have been replaced by per-plugin modules instead. Since both modules only had
one type, you can simply change
- `vim.autocomplete.*` -> `vim.autocomplete.nvim-cmp.*`
- `vim.autopairs.enable` -> `vim.autopairs.nvim-autopairs.enable`
## Changelog {#sec-release-0.7-changelog}
[ItsSorae](https://github.com/ItsSorae):
@ -67,6 +101,9 @@ everyone.
- Add dap-go for better dap configurations
- Make noice.nvim customizable
- Standardize border style options and add custom borders
- Remove `vim.disableDefaultRuntimePaths` in wrapper options.
- As nvf uses `$NVIM_APP_NAME` as of recent changes, we can safely assume any
configuration in `$XDG_CONFIG_HOME/nvf` is intentional.
[rust-tools.nvim]: https://github.com/simrat39/rust-tools.nvim
[rustaceanvim]: https://github.com/mrcjkb/rustaceanvim
@ -124,10 +161,29 @@ everyone.
- Replace `vim.lsp.nvimCodeActionMenu` with `vim.ui.fastaction`, see the
breaking changes section above for more details
- Add a `setupOpts` option to nvim-surround, which allows modifying options that
aren't defined in nvf. Move the alternate nvim-surround keybinds to use
`setupOpts`.
- Remove `autopairs.type`, and rename `autopairs.enable` to
`autopairs.nvim-autopairs.enable`. The new
[](#opt-vim.autopairs.nvim-autopairs.enable) supports `setupOpts` format by
default.
- Refactor of `nvim-cmp` and completion related modules
- Remove `autocomplete.type` in favor of per-plugin enable options such as
[](#opt-vim.autocomplete.nvim-cmp.enable).
- Deprecate legacy Vimsnip in favor of Luasnip, and integrate
friendly-snippets for bundled snippets. [](#opt-vim.snippets.luasnip.enable)
can be used to toggle Luasnip.
- Add sorting function options for completion sources under
[](#opt-vim.autocomplete.nvim-cmp.setupOpts.sorting.comparators)
[Neovim documentation on `vim.cmd`]: https://neovim.io/doc/user/lua.html#vim.cmd()
- Make Neovim's configuration file entirely Lua based. This comes with a few
breaking changes:
- `vim.configRC` has been removed. You will need to migrate your entries to
Neovim-compliant Lua code, and add them to `vim.luaConfigRC` instead.
Existing vimscript configurations may be preserved in `vim.cmd` functions.
@ -136,6 +192,8 @@ everyone.
has been introduced for setting up internal plugins. See the "DAG entries in
nvf" manual page for more information.
- Rewrite `vim.maps`, see the breaking changes section above.
[NotAShelf](https://github.com/notashelf):
[ts-error-translator.nvim]: https://github.com/dmmulroy/ts-error-translator.nvim
@ -212,7 +270,19 @@ everyone.
- Add LSP and Treesitter support for R under `vim.languages.R`.
- Add Otter support under `vim.lsp.otter` and an assert to prevent conflict with
ccc
- Add Neorg support under `vim.notes.neorg`
- Add LSP, diagnostics, formatter and Treesitter support for Kotlin under
`vim.languages.kotlin`
- changed default keybinds for leap.nvim to avoid altering expected behavior
[Bloxx12](https://github.com/Bloxx12):
[Bloxx12](https://github.com/Bloxx12)
- Add support for [base16 theming](https://github.com/RRethy/base16-nvim) under
`vim.theme`
- Fix internal breakage in `elixir-tools` setup.
[ksonj](https://github.com/ksonj):
- Add LSP support for Scala via
[nvim-metals](https://github.com/scalameta/nvim-metals)

View file

@ -172,6 +172,22 @@
"type": "github"
}
},
"plugin-base16": {
"flake": false,
"locked": {
"lastModified": 1716483968,
"narHash": "sha256-GRF/6AobXHamw8TZ3FjL7SI6ulcpwpcohsIuZeCSh2A=",
"owner": "rrethy",
"repo": "base16-nvim",
"rev": "6ac181b5733518040a33017dde654059cd771b7c",
"type": "github"
},
"original": {
"owner": "rrethy",
"repo": "base16-nvim",
"type": "github"
}
},
"plugin-bufdelete-nvim": {
"flake": false,
"locked": {
@ -191,11 +207,11 @@
"plugin-catppuccin": {
"flake": false,
"locked": {
"lastModified": 1716704960,
"narHash": "sha256-UDPS+1o8FQGkfqiG4GX4DNUI2pU5hIvagmfnWTKDb44=",
"lastModified": 1728131011,
"narHash": "sha256-j6F078taxuGzr3jngrc+Pc5I1kDdxTLMETgq6Xn4w/4=",
"owner": "catppuccin",
"repo": "nvim",
"rev": "5215ea59df6d0a7e27da9a5cd1165e06d1b04cbe",
"rev": "7be452ee067978cdc8b2c5f3411f0c71ffa612b9",
"type": "github"
},
"original": {
@ -300,6 +316,22 @@
"type": "github"
}
},
"plugin-cmp-luasnip": {
"flake": false,
"locked": {
"lastModified": 1696878902,
"narHash": "sha256-nUJJl2zyK/oSwz5RzI9j3gf9zpDfCImCYbPbVsyXgz8=",
"owner": "saadparwaiz1",
"repo": "cmp_luasnip",
"rev": "05a9ab28b53f71d1aece421ef32fee2cb857a843",
"type": "github"
},
"original": {
"owner": "saadparwaiz1",
"repo": "cmp_luasnip",
"type": "github"
}
},
"plugin-cmp-nvim-lsp": {
"flake": false,
"locked": {
@ -348,22 +380,6 @@
"type": "github"
}
},
"plugin-cmp-vsnip": {
"flake": false,
"locked": {
"lastModified": 1669100283,
"narHash": "sha256-2mkN03noOr5vBvRbSb35xZKorSH+8savQNZtgM9+QcM=",
"owner": "hrsh7th",
"repo": "cmp-vsnip",
"rev": "989a8a73c44e926199bfd05fa7a516d51f2d2752",
"type": "github"
},
"original": {
"owner": "hrsh7th",
"repo": "cmp-vsnip",
"type": "github"
}
},
"plugin-codewindow-nvim": {
"flake": false,
"locked": {
@ -572,6 +588,22 @@
"type": "github"
}
},
"plugin-friendly-snippets": {
"flake": false,
"locked": {
"lastModified": 1727061933,
"narHash": "sha256-yTsuV5unoujY0mhLINssYYBWCeefe+nJaxQHJKm7hlk=",
"owner": "rafamadriz",
"repo": "friendly-snippets",
"rev": "00ba9dd3df89509f95437b8d595553707c46d5ea",
"type": "github"
},
"original": {
"owner": "rafamadriz",
"repo": "friendly-snippets",
"type": "github"
}
},
"plugin-gesture-nvim": {
"flake": false,
"locked": {
@ -796,6 +828,22 @@
"type": "github"
}
},
"plugin-lua-utils-nvim": {
"flake": false,
"locked": {
"lastModified": 1708177208,
"narHash": "sha256-9ildzQEMkXKZ3LHq+khGFgRQFxlIXQclQ7QU3fcU1C4=",
"owner": "nvim-neorg",
"repo": "lua-utils.nvim",
"rev": "e565749421f4bbb5d2e85e37c3cef9d56553d8bd",
"type": "github"
},
"original": {
"owner": "nvim-neorg",
"repo": "lua-utils.nvim",
"type": "github"
}
},
"plugin-lualine": {
"flake": false,
"locked": {
@ -812,6 +860,22 @@
"type": "github"
}
},
"plugin-luasnip": {
"flake": false,
"locked": {
"lastModified": 1726165831,
"narHash": "sha256-nkaa1NGOI28Et2QitQB+Spv+J42QVdHE1oywteLcJJw=",
"owner": "L3MON4D3",
"repo": "LuaSnip",
"rev": "e808bee352d1a6fcf902ca1a71cee76e60e24071",
"type": "github"
},
"original": {
"owner": "L3MON4D3",
"repo": "LuaSnip",
"type": "github"
}
},
"plugin-mind-nvim": {
"flake": false,
"locked": {
@ -908,6 +972,38 @@
"type": "github"
}
},
"plugin-neorg": {
"flake": false,
"locked": {
"lastModified": 1727821831,
"narHash": "sha256-yfWQ6yKytu1jkWUtRZTVICslUWej6jVYv7frmSB7/6Q=",
"owner": "nvim-neorg",
"repo": "neorg",
"rev": "afc9a37bf021acb0853e95714c4c6436e1588286",
"type": "github"
},
"original": {
"owner": "nvim-neorg",
"repo": "neorg",
"type": "github"
}
},
"plugin-neorg-telescope": {
"flake": false,
"locked": {
"lastModified": 1722358034,
"narHash": "sha256-ei4uUqpIQjGKzu5ryu0Hlmis9TS9FJsYnjt4J4QdWlw=",
"owner": "nvim-neorg",
"repo": "neorg-telescope",
"rev": "ddb2556644cae922699a239bbb0fe16e25b084b7",
"type": "github"
},
"original": {
"owner": "nvim-neorg",
"repo": "neorg-telescope",
"type": "github"
}
},
"plugin-new-file-template-nvim": {
"flake": false,
"locked": {
@ -1149,6 +1245,22 @@
"type": "github"
}
},
"plugin-nvim-metals": {
"flake": false,
"locked": {
"lastModified": 1728295172,
"narHash": "sha256-ja/+MNxZ3H9io9jDwm5rhE6iKNi86a22eCOY75g19O8=",
"owner": "scalameta",
"repo": "nvim-metals",
"rev": "f861db9fda55939797ac1b05238c49b0dcdc3bdb",
"type": "github"
},
"original": {
"owner": "scalameta",
"repo": "nvim-metals",
"type": "github"
}
},
"plugin-nvim-navbuddy": {
"flake": false,
"locked": {
@ -1405,6 +1517,22 @@
"type": "github"
}
},
"plugin-pathlib-nvim": {
"flake": false,
"locked": {
"lastModified": 1724943804,
"narHash": "sha256-YhCJeNKlcjgg3q51UWFhuIEPzNueC8YTpeuPPJDndvw=",
"owner": "pysan3",
"repo": "pathlib.nvim",
"rev": "57e5598af6fe253761c1b48e0b59b7cd6699e2c1",
"type": "github"
},
"original": {
"owner": "pysan3",
"repo": "pathlib.nvim",
"type": "github"
}
},
"plugin-plenary-nvim": {
"flake": false,
"locked": {
@ -1741,22 +1869,6 @@
"type": "github"
}
},
"plugin-vim-vsnip": {
"flake": false,
"locked": {
"lastModified": 1704937299,
"narHash": "sha256-gvm6z4pgSULBVPukewRyjwxZ0vZgreQWbG/0kOB1QBo=",
"owner": "hrsh7th",
"repo": "vim-vsnip",
"rev": "02a8e79295c9733434aab4e0e2b8c4b7cea9f3a9",
"type": "github"
},
"original": {
"owner": "hrsh7th",
"repo": "vim-vsnip",
"type": "github"
}
},
"plugin-which-key": {
"flake": false,
"locked": {
@ -1802,6 +1914,7 @@
"nixpkgs": "nixpkgs",
"nmd": "nmd",
"plugin-alpha-nvim": "plugin-alpha-nvim",
"plugin-base16": "plugin-base16",
"plugin-bufdelete-nvim": "plugin-bufdelete-nvim",
"plugin-catppuccin": "plugin-catppuccin",
"plugin-ccc": "plugin-ccc",
@ -1810,10 +1923,10 @@
"plugin-cheatsheet-nvim": "plugin-cheatsheet-nvim",
"plugin-cinnamon-nvim": "plugin-cinnamon-nvim",
"plugin-cmp-buffer": "plugin-cmp-buffer",
"plugin-cmp-luasnip": "plugin-cmp-luasnip",
"plugin-cmp-nvim-lsp": "plugin-cmp-nvim-lsp",
"plugin-cmp-path": "plugin-cmp-path",
"plugin-cmp-treesitter": "plugin-cmp-treesitter",
"plugin-cmp-vsnip": "plugin-cmp-vsnip",
"plugin-codewindow-nvim": "plugin-codewindow-nvim",
"plugin-comment-nvim": "plugin-comment-nvim",
"plugin-copilot-cmp": "plugin-copilot-cmp",
@ -1827,6 +1940,7 @@
"plugin-fastaction-nvim": "plugin-fastaction-nvim",
"plugin-fidget-nvim": "plugin-fidget-nvim",
"plugin-flutter-tools": "plugin-flutter-tools",
"plugin-friendly-snippets": "plugin-friendly-snippets",
"plugin-gesture-nvim": "plugin-gesture-nvim",
"plugin-gitsigns-nvim": "plugin-gitsigns-nvim",
"plugin-glow-nvim": "plugin-glow-nvim",
@ -1841,13 +1955,17 @@
"plugin-lsp-signature": "plugin-lsp-signature",
"plugin-lspkind": "plugin-lspkind",
"plugin-lspsaga": "plugin-lspsaga",
"plugin-lua-utils-nvim": "plugin-lua-utils-nvim",
"plugin-lualine": "plugin-lualine",
"plugin-luasnip": "plugin-luasnip",
"plugin-mind-nvim": "plugin-mind-nvim",
"plugin-minimap-vim": "plugin-minimap-vim",
"plugin-modes-nvim": "plugin-modes-nvim",
"plugin-neo-tree-nvim": "plugin-neo-tree-nvim",
"plugin-neocord": "plugin-neocord",
"plugin-neodev-nvim": "plugin-neodev-nvim",
"plugin-neorg": "plugin-neorg",
"plugin-neorg-telescope": "plugin-neorg-telescope",
"plugin-new-file-template-nvim": "plugin-new-file-template-nvim",
"plugin-noice-nvim": "plugin-noice-nvim",
"plugin-none-ls": "plugin-none-ls",
@ -1863,6 +1981,7 @@
"plugin-nvim-docs-view": "plugin-nvim-docs-view",
"plugin-nvim-lightbulb": "plugin-nvim-lightbulb",
"plugin-nvim-lspconfig": "plugin-nvim-lspconfig",
"plugin-nvim-metals": "plugin-nvim-metals",
"plugin-nvim-navbuddy": "plugin-nvim-navbuddy",
"plugin-nvim-navic": "plugin-nvim-navic",
"plugin-nvim-neoclip": "plugin-nvim-neoclip",
@ -1879,6 +1998,7 @@
"plugin-orgmode-nvim": "plugin-orgmode-nvim",
"plugin-otter-nvim": "plugin-otter-nvim",
"plugin-oxocarbon": "plugin-oxocarbon",
"plugin-pathlib-nvim": "plugin-pathlib-nvim",
"plugin-plenary-nvim": "plugin-plenary-nvim",
"plugin-project-nvim": "plugin-project-nvim",
"plugin-registers": "plugin-registers",
@ -1900,7 +2020,6 @@
"plugin-vim-markdown": "plugin-vim-markdown",
"plugin-vim-repeat": "plugin-vim-repeat",
"plugin-vim-startify": "plugin-vim-startify",
"plugin-vim-vsnip": "plugin-vim-vsnip",
"plugin-which-key": "plugin-which-key",
"rnix-lsp": "rnix-lsp",
"systems": "systems_2"

View file

@ -206,6 +206,11 @@
flake = false;
};
plugin-nvim-metals = {
url = "github:scalameta/nvim-metals";
flake = false;
};
# Copying/Registers
plugin-registers = {
url = "github:tversteeg/registers.nvim";
@ -277,11 +282,6 @@
flake = false;
};
plugin-cmp-vsnip = {
url = "github:hrsh7th/cmp-vsnip";
flake = false;
};
plugin-cmp-path = {
url = "github:hrsh7th/cmp-path";
flake = false;
@ -292,9 +292,19 @@
flake = false;
};
plugin-cmp-luasnip = {
url = "github:saadparwaiz1/cmp_luasnip";
flake = false;
};
# snippets
plugin-vim-vsnip = {
url = "github:hrsh7th/vim-vsnip";
plugin-luasnip = {
url = "github:L3MON4D3/LuaSnip";
flake = false;
};
plugin-friendly-snippets = {
url = "github:rafamadriz/friendly-snippets";
flake = false;
};
@ -349,6 +359,11 @@
};
# Themes
plugin-base16 = {
url = "github:rrethy/base16-nvim";
flake = false;
};
plugin-tokyonight = {
url = "github:folke/tokyonight.nvim";
flake = false;
@ -631,6 +646,26 @@
flake = false;
};
plugin-lua-utils-nvim = {
url = "github:nvim-neorg/lua-utils.nvim";
flake = false;
};
plugin-pathlib-nvim = {
url = "github:pysan3/pathlib.nvim";
flake = false;
};
plugin-neorg = {
url = "github:nvim-neorg/neorg";
flake = false;
};
plugin-neorg-telescope = {
url = "github:nvim-neorg/neorg-telescope";
flake = false;
};
plugin-nui-nvim = {
# (required by noice.nvim)
url = "github:MunifTanjim/nui.nvim";

5
lib/attrsets.nix Normal file
View file

@ -0,0 +1,5 @@
{lib}: let
inherit (builtins) listToAttrs;
in {
mapListToAttrs = f: list: listToAttrs (map f list);
}

View file

@ -10,6 +10,7 @@
dag = import ./dag.nix {inherit lib;};
languages = import ./languages.nix {inherit lib;};
lists = import ./lists.nix {inherit lib;};
attrsets = import ./attrsets.nix {inherit lib;};
lua = import ./lua.nix {inherit lib;};
neovimConfiguration = import ../modules {inherit inputs lib;};
}

View file

@ -2,8 +2,8 @@
{lib}: let
inherit (builtins) isString getAttr;
inherit (lib.options) mkOption;
inherit (lib.attrsets) listToAttrs;
inherit (lib.types) bool;
inherit (lib.nvim.attrsets) mapListToAttrs;
in {
# Converts a boolean to a yes/no string. This is used in lots of
# configuration formats.
@ -12,8 +12,8 @@ in {
config,
diagnosticsProviders,
}:
listToAttrs
(map (v: let
mapListToAttrs
(v: let
type =
if isString v
then v
@ -26,7 +26,7 @@ in {
name = "${lang}-diagnostics-${type}";
value = diagnosticsProviders.${type}.nullConfig package;
})
config);
config;
mkEnable = desc:
mkOption {

View file

@ -1,8 +1,9 @@
{lib}: let
inherit (lib) isStringLike showOption showFiles getFiles mergeOneOption mergeEqualOption mkOptionType;
inherit (lib.types) anything attrsOf;
inherit (lib.options) showOption showFiles getFiles mergeOneOption mergeEqualOption;
inherit (lib.strings) isString isStringLike;
inherit (lib.types) anything attrsOf listOf mkOptionType;
inherit (lib.nvim.types) anythingConcatLists;
inherit (builtins) typeOf isAttrs any head concatLists stringLength;
inherit (builtins) typeOf isAttrs any head concatLists stringLength match;
in {
# HACK: Does this break anything in our case?
# A modified version of the nixpkgs anything type that concatenates lists
@ -51,6 +52,16 @@ in {
(mergeFunctions.${commonType} or mergeEqualOption) loc defs;
};
mergelessListOf = elemType: let
super = listOf elemType;
in
super
// {
name = "mergelessListOf";
description = "mergeless ${super.description}";
merge = mergeEqualOption;
};
char = mkOptionType {
name = "char";
description = "character";
@ -58,4 +69,11 @@ in {
check = value: stringLength value < 2;
merge = mergeEqualOption;
};
hexColor = mkOptionType {
name = "hex-color";
descriptionClass = "noun";
description = "RGB color in hex format";
check = v: isString v && (match "#?[0-9a-fA-F]{6}" v) != null;
};
}

View file

@ -6,10 +6,10 @@
typesDag = import ./dag.nix {inherit lib;};
typesPlugin = import ./plugins.nix {inherit inputs lib;};
typesLanguage = import ./languages.nix {inherit lib;};
typesCustom = import ./custom.nix {inherit lib;};
customTypes = import ./custom.nix {inherit lib;};
in {
inherit (typesDag) dagOf;
inherit (typesPlugin) pluginsOpt extraPluginType mkPluginSetupOption luaInline pluginType borderType;
inherit (typesLanguage) diagnostics mkGrammarOption;
inherit (typesCustom) anythingConcatLists char;
inherit (customTypes) anythingConcatLists char hexColor mergelessListOf;
}

View file

@ -1,5 +1,5 @@
{lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule;
inherit (lib.modules) mkRemovedOptionModule mkRenamedOptionModule;
in {
imports = [
# 2024-06-06
@ -14,5 +14,45 @@ in {
available under `vim.ui.fastaction` as a replacement. Simply remove everything under
`vim.lsp.nvimCodeActionMenu`, and set `vim.ui.fastaction.enable` to `true`.
'')
(mkRemovedOptionModule ["vim" "autopairs" "enable"] ''
vim.autopairs.enable has been removed in favor of per-plugin modules.
You can enable nvim-autopairs with vim.autopairs.nvim-autopairs.enable instead.
'')
(mkRemovedOptionModule ["vim" "autopairs" "type"] ''
vim.autopairs.type has been removed in favor of per-plugin modules.
You can enable nvim-autopairs with vim.autopairs.nvim-autopairs.enable instead.
'')
(mkRemovedOptionModule ["vim" "autocomplete" "enable"] ''
vim.autocomplete.enable has been removed in favor of per-plugin modules.
You can enable nvim-cmp with vim.autocomplete.nvim-cmp.enable instead.
'')
(mkRemovedOptionModule ["vim" "autocomplete" "type"] ''
vim.autocomplete.type has been removed in favor of per-plugin modules.
You can enable nvim-cmp with vim.autocomplete.nvim-cmp.enable instead.
'')
(mkRemovedOptionModule ["vim" "autocomplete" "sources"] ''
vim.autocomplete.sources has been removed in favor of per-plugin modules.
You can add nvim-cmp sources with vim.autocomplete.nvim-cmp.sources
instead.
'')
(mkRemovedOptionModule ["vim" "snippets" "vsnip" "enable"] ''
vim.snippets.vsnip.enable has been removed in favor of the more modern luasnip.
'')
(mkRenamedOptionModule ["vim" "lsp" "lspkind" "mode"] ["vim" "lsp" "lspkind" "setupOpts" "mode"])
# 2024-10-14
(mkRemovedOptionModule ["vim" "configRC"] ''
Please migrate your configRC sections to Neovim's Lua format, and
add them to `vim.luaConfigRC`.
See the v0.7 release notes for more information on why and how to
migrate your existing configurations to the new format.
'')
(mkRemovedOptionModule ["vim" "disableDefaultRuntimePaths"] ''
Nvf now uses $NVIM_APP_NAME so there is no longer the problem of
(accidental) leaking of user configuration.
'')
];
}

View file

@ -3,51 +3,75 @@
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.trivial) pipe;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.lists) flatten;
legacyMapModes = {
normal = ["n"];
insert = ["i"];
select = ["s"];
visual = ["v"];
terminal = ["t"];
normalVisualOp = ["n" "v" "o"];
visualOnly = ["n" "x"];
operator = ["o"];
insertCommand = ["i" "c"];
lang = ["l"];
command = ["c"];
};
cfg = config.vim;
in {
config = {
vim.maps = {
normal = mkIf cfg.disableArrows {
"<up>" = {
action = "<nop>";
noremap = false;
};
"<down>" = {
action = "<nop>";
noremap = false;
};
"<left>" = {
vim.keymaps = mkMerge [
(
mkIf cfg.disableArrows [
{
key = "<up>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
};
"<right>" = {
}
{
key = "<down>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
};
};
insert = mkIf cfg.disableArrows {
"<up>" = {
}
{
key = "<left>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
};
"<down>" = {
}
{
key = "<right>";
mode = ["n" "i"];
action = "<nop>";
noremap = false;
};
"<left>" = {
action = "<nop>";
noremap = false;
};
"<right>" = {
action = "<nop>";
noremap = false;
};
};
};
}
]
)
(
pipe cfg.maps
[
(mapAttrsToList (
oldMode: keybinds:
mapAttrsToList (
key: bind:
bind
// {
inherit key;
mode = legacyMapModes.${oldMode};
}
)
keybinds
))
flatten
]
)
];
};
}

View file

@ -1,101 +1,97 @@
{lib, ...}: let
inherit (lib.options) mkOption;
inherit (lib.types) bool str attrsOf nullOr submodule;
inherit (lib.options) mkOption literalMD;
inherit (lib.types) either str listOf attrsOf nullOr submodule;
inherit (lib.nvim.config) mkBool;
# Most of the keybindings code is highly inspired by pta2002/nixvim.
# Thank you!
mapConfigOptions = {
silent =
mkBool false
"Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
nowait =
mkBool false
"Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
script =
mkBool false
"Equivalent to adding <script> to a map.";
expr =
mkBool false
"Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
unique =
mkBool false
"Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
noremap =
mkBool true
"Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
desc = mkOption {
type = nullOr str;
default = null;
description = "A description of this keybind, to be shown in which-key, if you have it enabled.";
};
};
mapOption = submodule {
options =
mapConfigOptions
// {
action = mkOption {
type = str;
description = "The action to execute.";
description = "The command to execute.";
};
lua = mkOption {
type = bool;
description = ''
lua = mkBool false ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
default = false;
silent = mkBool true "Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
nowait = mkBool false "Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
script = mkBool false "Equivalent to adding <script> to a map.";
expr = mkBool false "Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
unique = mkBool false "Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
noremap = mkBool true "Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
};
mapType = submodule {
options =
mapConfigOptions
// {
key = mkOption {
type = str;
description = "The key that triggers this keybind.";
};
mode = mkOption {
type = either str (listOf str);
description = ''
The short-name of the mode to set the keymapping for. Passing an empty string is the equivalent of `:map`.
See `:help map-modes` for a list of modes.
'';
example = literalMD ''`["n" "v" "c"]` for normal, visual and command mode'';
};
};
};
mapOptions = mode:
legacyMapOption = mode:
mkOption {
description = "Mappings for ${mode} mode";
type = attrsOf mapOption;
type = attrsOf (submodule {
options = mapConfigOptions;
});
default = {};
};
in {
options.vim = {
maps = mkOption {
type = submodule {
options = {
normal = mapOptions "normal";
insert = mapOptions "insert";
select = mapOptions "select";
visual = mapOptions "visual and select";
terminal = mapOptions "terminal";
normalVisualOp = mapOptions "normal, visual, select and operator-pending (same as plain 'map')";
visualOnly = mapOptions "visual only";
operator = mapOptions "operator-pending";
insertCommand = mapOptions "insert and command-line";
lang = mapOptions "insert, command-line and lang-arg";
command = mapOptions "command-line";
};
};
default = {};
description = ''
Custom keybindings for any mode.
For plain maps (e.g. just 'map' or 'remap') use `maps.normalVisualOp`.
'';
keymaps = mkOption {
type = listOf mapType;
description = "Custom keybindings.";
example = ''
maps = {
normal."<leader>m" = {
vim.keymaps = [
{
key = "<leader>m";
mode = "n";
silent = true;
action = "<cmd>make<CR>";
}; # Same as nnoremap <leader>m <silent> <cmd>make<CR>
};
action = ":make<CR>";
}
{
key = "<leader>l";
mode = ["n" "x"];
silent = true;
action = "<cmd>cnext<CR>";
}
];
'';
default = {};
};
maps = {
normal = legacyMapOption "normal";
insert = legacyMapOption "insert";
select = legacyMapOption "select";
visual = legacyMapOption "visual and select";
terminal = legacyMapOption "terminal";
normalVisualOp = legacyMapOption "normal, visual, select and operator-pending (same as plain 'map')";
visualOnly = legacyMapOption "visual only";
operator = legacyMapOption "operator-pending";
insertCommand = legacyMapOption "insert and command-line";
lang = legacyMapOption "insert, command-line and lang-arg";
command = legacyMapOption "command-line";
};
};
}

View file

@ -34,6 +34,8 @@ in {
"copilot-cmp"
];
vim.autocomplete.nvim-cmp.sources = {copilot = "[Copilot]";};
vim.pluginRC.copilot = entryAnywhere ''
require("copilot").setup(${toLuaObject cfg.setupOpts})

View file

@ -4,16 +4,17 @@
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.trivial) boolToString;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.autopairs;
cfg = config.vim.autopairs.nvim-autopairs;
in {
config = mkIf cfg.enable {
vim.startPlugins = ["nvim-autopairs"];
vim.pluginRC.autopairs = entryAnywhere ''
require("nvim-autopairs").setup({ map_cr = ${boolToString (!config.vim.autocomplete.enable)} })
vim = {
startPlugins = ["nvim-autopairs"];
pluginRC.autopairs = entryAnywhere ''
require('nvim-autopairs').setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

@ -1,21 +1,14 @@
{lib, ...}: let
inherit (lib) mkRemovedOptionModule;
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum;
inherit (lib.options) mkEnableOption;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
imports = [
(mkRemovedOptionModule ["vim" "autopairs" "nvim-compe"] "nvim-compe is deprecated and no longer suported.")
];
options.vim = {
autopairs = {
enable = mkEnableOption "autopairs" // {default = false;};
type = mkOption {
type = enum ["nvim-autopairs"];
default = "nvim-autopairs";
description = "Set the autopairs type. Options: nvim-autopairs [nvim-autopairs]";
};
};
options.vim.autopairs.nvim-autopairs = {
enable = mkEnableOption "autopairs";
setupOpts = mkPluginSetupOption "nvim-autopairs" {};
};
}

View file

@ -12,9 +12,7 @@
inherit (self.options.vim.comments.comment-nvim) mappings;
in {
config = mkIf cfg.enable {
vim.startPlugins = [
"comment-nvim"
];
vim.startPlugins = ["comment-nvim"];
vim.maps.normal = mkMerge [
(mkBinding cfg.mappings.toggleOpLeaderLine "<Plug>(comment_toggle_linewise)" mappings.toggleOpLeaderLine.description)
@ -36,7 +34,7 @@ in {
mappings.toggleCurrentBlock.description)
];
vim.maps.visualOnly = mkMerge [
vim.maps.visual = mkMerge [
(mkBinding cfg.mappings.toggleSelectedLine "<Plug>(comment_toggle_linewise_visual)" mappings.toggleSelectedLine.description)
(mkBinding cfg.mappings.toggleSelectedBlock "<Plug>(comment_toggle_blockwise_visual)" mappings.toggleSelectedBlock.description)
];

View file

@ -3,246 +3,92 @@
config,
...
}: let
inherit (builtins) toJSON;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) attrNames mapAttrsToList;
inherit (lib.strings) concatMapStringsSep concatStringsSep optionalString;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetLuaBinding;
inherit (lib.nvim.dag) entryAnywhere entryAfter;
inherit (lib.modules) mkIf;
inherit (lib.strings) optionalString;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.lua) toLuaObject;
inherit (builtins) attrNames;
cfg = config.vim.autocomplete;
lspkindEnabled = config.vim.lsp.enable && config.vim.lsp.lspkind.enable;
self = import ./nvim-cmp.nix {inherit lib;};
mappingDefinitions = self.options.vim.autocomplete.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
builtSources =
concatMapStringsSep
"\n"
(n: "{ name = '${n}'},")
(attrNames cfg.sources);
builtMaps =
concatStringsSep
"\n"
(mapAttrsToList
(n: v:
if v == null
then ""
else "${n} = '${v}',")
cfg.sources);
dagPlacement =
if lspkindEnabled
then entryAfter ["lspkind"]
else entryAnywhere;
cfg = config.vim.autocomplete.nvim-cmp;
luasnipEnable = config.vim.snippets.luasnip.enable;
inherit (cfg) mappings;
in {
config = mkIf cfg.enable {
vim.startPlugins = [
vim = {
startPlugins = [
"nvim-cmp"
"cmp-buffer"
"cmp-vsnip"
"cmp-path"
"vim-vsnip"
];
vim.autocomplete.sources = {
"nvim-cmp" = null;
"vsnip" = "[VSnip]";
"buffer" = "[Buffer]";
"crates" = "[Crates]";
"path" = "[Path]";
"copilot" = "[Copilot]";
autocomplete.nvim-cmp.sources = {
nvim-cmp = null;
buffer = "[Buffer]";
path = "[Path]";
};
vim.maps.insert = mkMerge [
(mkSetLuaBinding mappings.complete ''
require('cmp').complete
'')
(let
defaultKeys =
if config.vim.autopairs.enable
then "require('nvim-autopairs').autopairs_cr()"
else "vim.api.nvim_replace_termcodes(${toJSON mappings.confirm.value}, true, false, true)";
in
mkSetLuaBinding mappings.confirm ''
function()
if not require('cmp').confirm({ select = true }) then
vim.fn.feedkeys(${defaultKeys}, 'n')
end
end
'')
(mkSetLuaBinding mappings.next ''
function()
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
autocomplete.nvim-cmp.setupOpts = {
sources = map (s: {name = s;}) (attrNames cfg.sources);
local cmp = require('cmp')
# TODO: try to get nvim-cmp to follow global border style
window = mkIf config.vim.ui.borders.enable {
completion = mkLuaInline "cmp.config.window.bordered()";
documentation = mkLuaInline "cmp.config.window.bordered()";
};
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
formatting.format = cfg.format;
};
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn['vsnip#available'](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
local termcode = vim.api.nvim_replace_termcodes(${toJSON mappings.next.value}, true, false, true)
vim.fn.feedkeys(termcode, 'n')
end
end
'')
(mkSetLuaBinding mappings.previous ''
function()
local cmp = require('cmp')
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn['vsnip#available'](-1) == 1 then
feedkeys("<Plug>(vsnip-jump-prev)", "")
end
end
'')
(mkSetLuaBinding mappings.close ''
require('cmp').mapping.abort()
'')
(mkSetLuaBinding mappings.scrollDocsUp ''
require('cmp').mapping.scroll_docs(-4)
'')
(mkSetLuaBinding mappings.scrollDocsDown ''
require('cmp').mapping.scroll_docs(4)
'')
];
vim.maps.command = mkMerge [
(mkSetLuaBinding mappings.complete ''
require('cmp').complete
'')
(mkSetLuaBinding mappings.close ''
require('cmp').mapping.close()
'')
(mkSetLuaBinding mappings.scrollDocsUp ''
require('cmp').mapping.scroll_docs(-4)
'')
(mkSetLuaBinding mappings.scrollDocsDown ''
require('cmp').mapping.scroll_docs(4)
'')
];
vim.maps.select = mkMerge [
(mkSetLuaBinding mappings.next ''
function()
local cmp = require('cmp')
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn['vsnip#available'](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
local termcode = vim.api.nvim_replace_termcodes(${toJSON mappings.next.value}, true, false, true)
vim.fn.feedkeys(termcode, 'n')
end
end
'')
(mkSetLuaBinding mappings.previous ''
function()
local cmp = require('cmp')
local feedkey = function(key, mode)
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true)
end
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn['vsnip#available'](-1) == 1 then
feedkeys("<Plug>(vsnip-jump-prev)", "")
end
end
'')
];
# TODO: alternative snippet engines to vsnip
# https://github.com/hrsh7th/nvim-cmp/blob/main/doc/cmp.txt#L82
vim.pluginRC.completion = mkIf (cfg.type == "nvim-cmp") (dagPlacement ''
local nvim_cmp_menu_map = function(entry, vim_item)
-- name for each source
vim_item.menu = ({
${builtMaps}
})[entry.source.name]
return vim_item
end
${optionalString lspkindEnabled ''
lspkind_opts.before = ${cfg.formatting.format}
''}
local cmp = require'cmp'
cmp.setup({
${optionalString config.vim.ui.borders.enable ''
-- explicitly enabled by setting ui.borders.enable = true
-- TODO: try to get nvim-cmp to follow global border style
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
''}
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
sources = {
${builtSources}
},
completion = {
completeopt = 'menu,menuone,noinsert',
${optionalString (!cfg.alwaysComplete) "autocomplete = false"}
},
formatting = {
format =
${
if lspkindEnabled
then "lspkind.cmp_format(lspkind_opts)"
else cfg.formatting.format
},
}
})
${optionalString (config.vim.autopairs.enable && config.vim.autopairs.type == "nvim-autopairs") ''
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done({ map_char = { text = ""} }))
''}
pluginRC.nvim-cmp = mkIf cfg.enable (entryAfter ["autopairs" "luasnip"] ''
${optionalString luasnipEnable "local luasnip = require('luasnip')"}
local cmp = require("cmp")
cmp.setup(${toLuaObject cfg.setupOpts})
'');
vim.snippets.vsnip.enable =
if (cfg.type == "nvim-cmp")
then true
else config.vim.snippets.vsnip.enable;
# `cmp` and `luasnip` are defined above, in the `nvim-cmp` section
autocomplete.nvim-cmp.setupOpts.mapping = {
${mappings.complete} = mkLuaInline "cmp.mapping.complete()";
${mappings.close} = mkLuaInline "cmp.mapping.abort()";
${mappings.scrollDocsUp} = mkLuaInline "cmp.mapping.scroll_docs(-4)";
${mappings.scrollDocsDown} = mkLuaInline "cmp.mapping.scroll_docs(4)";
${mappings.confirm} = mkLuaInline "cmp.mapping.confirm({ select = true })";
${mappings.next} = mkLuaInline ''
cmp.mapping(function(fallback)
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
if cmp.visible() then
cmp.select_next_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(1) then
luasnip.jump(1)
''}
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end)
'';
${mappings.previous} = mkLuaInline ''
cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
''}
else
fallback()
end
end)
'';
};
};
};
}

View file

@ -1,4 +1,4 @@
_: {
{
imports = [
./config.nix
./nvim-cmp.nix

View file

@ -1,16 +1,56 @@
{lib, ...}: let
inherit (lib.options) mkEnableOption mkOption literalMD;
{
lib,
config,
...
}: let
inherit (lib.options) mkEnableOption mkOption literalExpression literalMD;
inherit (lib.types) str attrsOf nullOr either;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.types) enum attrsOf nullOr str bool;
in {
options.vim = {
autocomplete = {
enable = mkEnableOption "autocomplete" // {default = false;};
inherit (lib.nvim.types) mkPluginSetupOption luaInline mergelessListOf;
inherit (lib.nvim.lua) toLuaObject;
inherit (builtins) isString;
alwaysComplete = mkOption {
type = bool;
description = "Automatically show completion.";
default = true;
cfg = config.vim.autocomplete.nvim-cmp;
in {
options.vim.autocomplete.nvim-cmp = {
enable = mkEnableOption "nvim-cmp";
setupOpts = mkPluginSetupOption "the autocomplete plugin" {
completion.completeopt = mkOption {
type = str;
default = "menu,menuone,noinsert";
description = ''
A comma-separated list of options for completion.
See `:help completeopt` for the complete list.
'';
};
sorting.comparators = mkOption {
type = mergelessListOf (either str luaInline);
default = [
"offset"
"exact"
"score"
"kind"
"length"
"sort_text"
];
description = ''
The comparator functions used for sorting completions.
You can either pass a valid inline lua function
(see `:help cmp-config.sorting.comparators`),
or a string, in which case the builtin comparator with that name will
be used.
'';
apply = map (
c:
if isString c
then mkLuaInline ("cmp.config.compare." + c)
else c
);
};
};
mappings = {
@ -23,50 +63,41 @@ in {
scrollDocsDown = mkMappingOption "Scroll docs down [nvim-cmp]" "<C-f>";
};
type = mkOption {
type = enum ["nvim-cmp"];
default = "nvim-cmp";
description = "Set the autocomplete plugin. Options: [nvim-cmp]";
};
sources = mkOption {
description = ''
Attribute set of source names for nvim-cmp.
If an attribute set is provided, then the menu value of
`vim_item` in the format will be set to the value (if
utilizing the `nvim_cmp_menu_map` function).
Note: only use a single attribute name per attribute set
'';
type = attrsOf (nullOr str);
default = {};
example = ''
{nvim-cmp = null; buffer = "[Buffer]";}
'';
};
formatting = {
format = mkOption {
description = ''
The function used to customize the appearance of the completion menu.
If [](#opt-vim.lsp.lspkind.enable) is true, then the function
will be called before modifications from lspkind.
Default is to call the menu mapping function.
type = luaInline;
default = mkLuaInline ''
function(entry, vim_item)
vim_item.menu = (${toLuaObject cfg.sources})[entry.source.name]
return vim_item
end
'';
type = str;
default = "nvim_cmp_menu_map";
example = literalMD ''
defaultText = literalMD ''
```lua
function(entry, vim_item)
vim_item.menu = (''${toLuaObject config.vim.autocomplete.nvim-cmp.sources})[entry.source.name]
return vim_item
end
```
'';
description = ''
The function used to customize the completion menu entires. This is
outside of `setupOpts` to allow for an easier integration with
lspkind.nvim.
See `:help cmp-config.formatting.format`.
'';
};
};
sources = mkOption {
type = attrsOf (nullOr str);
default = {};
description = "The list of sources used by nvim-cmp";
example = literalExpression ''
{
nvim-cmp = null;
buffer = "[Buffer]";
}
'';
};
};
}

View file

@ -16,9 +16,10 @@
in {
config = mkMerge [
(mkIf cfg.enable {
vim.startPlugins = ["nvim-dap"];
vim = {
startPlugins = ["nvim-dap"];
vim.pluginRC =
pluginRC =
{
# TODO customizable keymaps
nvim-dap = entryAnywhere ''
@ -28,7 +29,7 @@ in {
}
// mapAttrs (_: v: (entryAfter ["nvim-dap"] v)) cfg.sources;
vim.maps.normal = mkMerge [
maps.normal = mkMerge [
(mkSetLuaBinding mappings.continue "require('dap').continue")
(mkSetLuaBinding mappings.restart "require('dap').restart")
(mkSetLuaBinding mappings.terminate "require('dap').terminate")
@ -47,11 +48,13 @@ in {
(mkSetLuaBinding mappings.goUp "require('dap').up")
(mkSetLuaBinding mappings.goDown "require('dap').down")
];
};
})
(mkIf (cfg.enable && cfg.ui.enable) {
vim.startPlugins = ["nvim-dap-ui" "nvim-nio"];
vim = {
startPlugins = ["nvim-dap-ui" "nvim-nio"];
vim.pluginRC.nvim-dap-ui = entryAfter ["nvim-dap"] (''
pluginRC.nvim-dap-ui = entryAfter ["nvim-dap"] (''
local dapui = require("dapui")
dapui.setup()
''
@ -66,7 +69,8 @@ in {
dapui.close()
end
'');
vim.maps.normal = mkSetLuaBinding mappings.toggleDapUI "require('dapui').toggle";
maps.normal = mkSetLuaBinding mappings.toggleDapUI "require('dapui').toggle";
};
})
];
}

View file

@ -8,6 +8,7 @@ in {
./css.nix
./elixir.nix
./go.nix
./kotlin.nix
./html.nix
./java.nix
./lua.nix
@ -19,6 +20,7 @@ in {
./python.nix
./r.nix
./rust.nix
./scala.nix
./sql.nix
./svelte.nix
./tailwind.nix

View file

@ -0,0 +1,107 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.meta) getExe;
inherit (lib.nvim.languages) diagnosticsToLua;
inherit (lib.types) package;
inherit (lib.nvim.types) mkGrammarOption diagnostics;
inherit (lib.lists) isList;
inherit (lib.nvim.lua) expToLua;
cfg = config.vim.languages.kotlin;
defaultDiagnosticsProvider = ["ktlint"];
diagnosticsProviders = {
ktlint = {
package = pkgs.ktlint;
nullConfig = pkg: ''
table.insert(
ls_sources,
null_ls.builtins.diagnostics.ktlint.with({
command = "${getExe pkg}",
})
)
'';
};
};
in {
options.vim.languages.kotlin = {
enable = mkEnableOption "Kotlin/HCL support";
treesitter = {
enable = mkEnableOption "Kotlin treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "kotlin";
};
lsp = {
enable = mkEnableOption "Kotlin LSP support" // {default = config.vim.languages.enableLSP;};
package = mkOption {
description = "kotlin_language_server package with Kotlin runtime";
type = package;
example = literalExpression ''
pkgs.symlinkJoin {
name = "kotlin-language-server-wrapped";
paths = [pkgs.kotlin-language-server];
nativeBuildInputs = [pkgs.makeWrapper];
postBuild = '''
wrapProgram $out/bin/kotlin-language-server \
--prefix PATH : ''${pkgs.kotlin}/bin
''';
};
'';
default = pkgs.kotlin-language-server;
};
};
extraDiagnostics = {
enable = mkEnableOption "extra Kotlin diagnostics" // {default = config.vim.languages.enableExtraDiagnostics;};
types = diagnostics {
langDesc = "Kotlin";
inherit diagnosticsProviders;
inherit defaultDiagnosticsProvider;
};
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package];
})
(mkIf cfg.extraDiagnostics.enable {
vim.lsp.null-ls.enable = true;
vim.lsp.null-ls.sources = diagnosticsToLua {
lang = "kotlin";
config = cfg.extraDiagnostics.types;
inherit diagnosticsProviders;
};
})
(mkIf cfg.lsp.enable {
vim.lsp.lspconfig.enable = true;
vim.lsp.lspconfig.sources.kotlin_language_server = ''
lspconfig.kotlin_language_server.setup {
capabilities = capabilities,
root_dir = lspconfig.util.root_pattern("main.kt", ".git"),
on_attach=default_on_attach,
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

@ -9,7 +9,7 @@
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.strings) optionalString;
inherit (lib.trivial) boolToString;
inherit (lib.lists) isList optionals;
inherit (lib.lists) isList;
inherit (lib.types) bool package str listOf either enum;
inherit (lib.nvim.types) mkGrammarOption;
inherit (lib.nvim.lua) expToLua;
@ -101,7 +101,7 @@ in {
vim = {
startPlugins = ["crates-nvim"];
lsp.null-ls.enable = mkIf cfg.crates.codeActions true;
autocomplete.sources = {"crates" = "[Crates]";};
autocomplete.nvim-cmp.sources = {crates = "[Crates]";};
pluginRC.rust-crates = entryAnywhere ''
require('crates').setup {
null_ls = {

View file

@ -0,0 +1,149 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.generators) mkLuaInline;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.types) mkGrammarOption luaInline;
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
inherit (lib.strings) optionalString;
inherit (lib.types) attrsOf anything bool;
listCommandsAction =
if config.vim.telescope.enable
then ''require("telescope").extensions.metals.commands()''
else ''require("metals").commands()'';
cfg = config.vim.languages.scala;
usingDap = config.vim.debugger.nvim-dap.enable && cfg.dap.enable;
usingLualine = config.vim.statusline.lualine.enable;
in {
options.vim.languages.scala = {
enable = mkEnableOption "Scala language support";
treesitter = {
enable = mkEnableOption "Scala treesitter" // {default = config.vim.languages.enableTreesitter;};
package = mkGrammarOption pkgs "scala";
};
lsp = {
enable = mkEnableOption "Scala LSP support (metals)" // {default = config.vim.languages.enableLSP;};
package = mkPackageOption pkgs "metals" {
default = ["metals"];
};
extraMappings = {
listCommands = mkMappingOption "List Metals commands" "<leader>lc";
};
extraSettings = mkOption {
type = attrsOf anything;
description = "Extra settings passed to the metals config. Check nvim-metals docs for available options";
default = {
showImplicitArguments = true;
showImplicitConversionsAndClasses = true;
showInferredType = true;
excludedPackages = [
"akka.actor.typed.javadsl"
"com.github.swagger.akka.javadsl"
];
};
};
};
dap = {
enable = mkEnableOption "Scala Debug Adapter support (metals)" // {default = config.vim.languages.enableDAP;};
config = mkOption {
description = "Lua configuration for dap";
type = luaInline;
default = mkLuaInline ''
dap.configurations.scala = {
{
type = "scala",
request = "launch",
name = "RunOrTest",
metals = {
runType = "runOrTestFile",
--args = { "firstArg", "secondArg", "thirdArg" }, -- here just as an example
},
},
{
type = "scala",
request = "launch",
name = "Test Target",
metals = {
runType = "testTarget",
},
},
}
'';
};
};
fixShortmess = mkOption {
type = bool;
description = "Remove the 'F' flag from shortmess to allow messages to be shown. Without doing this, autocommands that deal with filetypes prohibit messages from being shown";
default = true;
};
};
config = mkIf cfg.enable (
mkMerge [
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.package];
})
(mkIf (cfg.lsp.enable || cfg.dap.enable) {
vim = {
startPlugins = ["nvim-metals"];
pluginRC.nvim-metals = entryAfter ["lsp-setup"] ''
local metals_caps = capabilities -- from lsp-setup
local attach_metals_keymaps = function(client, bufnr)
attach_keymaps(client, bufnr) -- from lsp-setup
vim.api.nvim_buf_set_keymap(bufnr, 'n', '${cfg.lsp.extraMappings.listCommands}', '<cmd>lua ${listCommandsAction}<CR>', {noremap=true, silent=true, desc='Show all Metals commands'})
end
metals_config = require('metals').bare_config()
${optionalString usingLualine "metals_config.init_options.statusBarProvider = 'on'"}
metals_config.capabilities = metals_caps
metals_config.on_attach = function(client, bufnr)
${optionalString usingDap "require('metals').setup_dap()"}
attach_metals_keymaps(client, bufnr)
end
metals_config.settings = ${toLuaObject cfg.lsp.extraSettings}
metals_config.settings.metalsBinaryPath = "${cfg.lsp.package}/bin/metals"
metals_config.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(
vim.lsp.diagnostic.on_publish_diagnostics, {
virtual_text = {
prefix = '',
}
}
)
${optionalString cfg.fixShortmess ''vim.opt_global.shortmess:remove("F")''}
local lsp_group = vim.api.nvim_create_augroup('lsp', { clear = true })
vim.api.nvim_create_autocmd('FileType', {
group = lsp_group,
pattern = {'java', 'scala', 'sbt'},
callback = function()
require('metals').initialize_or_attach(metals_config)
end,
})
'';
};
})
]
);
}

View file

@ -11,7 +11,7 @@
inherit (lib.nvim.binds) addDescriptionsToMappings;
cfg = config.vim.lsp;
usingNvimCmp = config.vim.autocomplete.enable && config.vim.autocomplete.type == "nvim-cmp";
usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
self = import ./module.nix {inherit config lib pkgs;};
mappingDefinitions = self.options.vim.lsp.mappings;
@ -25,7 +25,7 @@ in {
vim = {
startPlugins = optional usingNvimCmp "cmp-nvim-lsp";
autocomplete.sources = {"nvim_lsp" = "[LSP]";};
autocomplete.nvim-cmp.sources = {nvim_lsp = "[LSP]";};
pluginRC.lsp-setup = ''
vim.g.formatsave = ${boolToString cfg.formatOnSave};

View file

@ -3,18 +3,32 @@
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.modules) mkIf mkForce;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.lsp;
cfg = config.vim.lsp.lspkind;
in {
config = mkIf (cfg.enable && cfg.lspkind.enable) {
vim.startPlugins = ["lspkind"];
vim.pluginRC.lspkind = entryAnywhere ''
local lspkind = require'lspkind'
local lspkind_opts = {
mode = '${cfg.lspkind.mode}'
}
config = mkIf cfg.enable {
assertions = [
{
assertion = config.vim.autocomplete.nvim-cmp.enable;
message = ''
While lspkind supports Neovim's native lsp upstream, using that over
nvim-cmp isn't recommended, nor supported by nvf.
Please migrate to nvim-cmp if you want to use lspkind.
'';
}
];
vim = {
startPlugins = ["lspkind"];
lsp.lspkind.setupOpts.before = config.vim.autocomplete.nvim-cmp.format;
autocomplete.nvim-cmp.setupOpts.formatting.format = mkForce (mkLuaInline ''
require("lspkind").cmp_format(${toLuaObject cfg.setupOpts})
'');
};
};
}

View file

@ -1,16 +1,22 @@
{lib, ...}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) enum;
inherit (lib.types) enum nullOr;
inherit (lib.nvim.types) mkPluginSetupOption luaInline;
in {
options.vim.lsp = {
lspkind = {
options.vim.lsp.lspkind = {
enable = mkEnableOption "vscode-like pictograms for lsp [lspkind]";
setupOpts = mkPluginSetupOption "lspkind.nvim" {
mode = mkOption {
description = "Defines how annotations are shown";
type = enum ["text" "text_symbol" "symbol_text" "symbol"];
default = "symbol_text";
};
before = mkOption {
description = "The function that will be called before lspkind's modifications are applied";
type = nullOr luaInline;
default = null;
};
};
};
}

View file

@ -2,6 +2,7 @@
imports = [
./obsidian
./orgmode
./neorg
./mind-nvim
./todo-comments
];

View file

@ -0,0 +1,41 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.binds) pushDownDefault;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.notes.neorg;
in {
config = mkIf cfg.enable (mkMerge [
{
vim = {
startPlugins = [
"lua-utils-nvim"
"nui-nvim"
"nvim-nio"
"pathlib-nvim"
"plenary-nvim"
"neorg"
"neorg-telescope"
];
binds.whichKey.register = pushDownDefault {
"<leader>o" = "+Notes";
};
pluginRC.neorg = entryAnywhere ''
require('neorg').setup(${toLuaObject cfg.setupOpts})
'';
};
}
(mkIf cfg.treesitter.enable {
vim.treesitter.enable = true;
vim.treesitter.grammars = [cfg.treesitter.norgPackage];
})
]);
}

View file

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

View file

@ -0,0 +1,50 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) submodule listOf str;
inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption;
in {
options.vim.notes.neorg = {
enable = mkEnableOption ''
Neorg: An intuitive note-taking and organization tool with a structured nested syntax.
'';
setupOpts = mkPluginSetupOption "Neorg" {
load = {
"core.defaults" = mkOption {
default = {};
description = ''
all of the most important modules that any user would want to have a "just works" experience
'';
type = submodule {
options = {
enable = mkEnableOption ''
all of the most important modules that any user would want to have a "just works" experience
'';
config = {
disable = mkOption {
description = ''
list of modules from to be disabled from core.defaults
'';
type = listOf str;
default = [];
example = ["core.autocommands" "core.itero"];
};
};
};
};
};
};
};
treesitter = {
enable = mkEnableOption "Neorg treesitter" // {default = config.vim.languages.enableTreesitter;};
norgPackage = mkGrammarOption pkgs "norg";
};
};
}

View file

@ -45,10 +45,10 @@ in {
completion = {
nvim_cmp = mkOption {
# if using nvim-cmp, otherwise set to false
# If using nvim-cmp, otherwise set to false
type = bool;
description = "If using nvim-cmp, otherwise set to false";
default = config.vim.autocomplete.type == "nvim-cmp";
default = config.vim.autocomplete.nvim-cmp.enable;
};
};
};

View file

@ -1,5 +1,5 @@
{
imports = [
./vsnip
./luasnip
];
}

View file

@ -0,0 +1,17 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.vim.snippets.luasnip;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["luasnip" "cmp-luasnip"] ++ cfg.providers;
autocomplete.nvim-cmp.sources = {luasnip = "[LuaSnip]";};
pluginRC.luasnip = cfg.loaders;
};
};
}

View file

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

View file

@ -0,0 +1,36 @@
{lib, ...}: let
inherit (lib.options) mkEnableOption mkOption literalExpression literalMD;
inherit (lib.types) listOf lines;
inherit (lib.nvim.types) pluginType;
in {
options.vim.snippets.luasnip = {
enable = mkEnableOption "luasnip";
providers = mkOption {
type = listOf pluginType;
default = ["friendly-snippets"];
description = ''
The snippet provider packages.
::: {.note}
These are simply appended to {option} `vim.startPlugins`.
:::
'';
example = literalExpression "[\"vimPlugins.vim-snippets\"]";
};
loaders = mkOption {
type = lines;
default = "require('luasnip.loaders.from_vscode').lazy_load()";
defaultText = literalMD ''
```lua
require('luasnip.loaders.from_vscode').lazy_load()
```
'';
description = "Lua code used to load snippet providers.";
example = literalMD ''
```lua
require("luasnip.loaders.from_snipmate").lazy_load()
```
'';
};
};
}

View file

@ -1,13 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.vim.snippets.vsnip;
in {
config = mkIf cfg.enable {
vim.startPlugins = ["vim-vsnip"];
};
}

View file

@ -1,5 +0,0 @@
{
imports = [
./vsnip.nix
];
}

View file

@ -1,7 +0,0 @@
{lib, ...}: let
inherit (lib.options) mkEnableOption;
in {
options.vim.snippets.vsnip = {
enable = mkEnableOption "vim-vsnip: snippet LSP/VSCode's format";
};
}

View file

@ -4,7 +4,14 @@
}: let
inherit (lib.strings) optionalString;
inherit (lib.trivial) boolToString warnIf;
inherit (lib.nvim.lua) toLuaObject;
in {
base16 = {
setup = {base16-colors, ...}: ''
-- Base16 theme
require('base16-colorscheme').setup(${toLuaObject base16-colors})
'';
};
onedark = {
setup = {style ? "dark", ...}: ''
-- OneDark theme
@ -20,6 +27,7 @@ in {
setup = {
style ? "night",
transparent,
...
}: ''
require('tokyonight').setup {
transparent = ${boolToString transparent};
@ -42,6 +50,7 @@ in {
setup = {
style ? "mocha",
transparent ? false,
...
}: ''
-- Catppuccin theme
require('catppuccin').setup {

View file

@ -5,31 +5,52 @@
}: let
inherit (lib.options) mkOption;
inherit (lib.attrsets) attrNames;
inherit (lib.strings) hasPrefix;
inherit (lib.types) bool lines enum;
inherit (lib.modules) mkIf;
inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (lib.nvim.dag) entryBefore;
inherit (lib.nvim.types) hexColor;
cfg = config.vim.theme;
supportedThemes = import ./supported-themes.nix {
inherit lib config;
};
numbers = ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"];
base16Options =
mapListToAttrs (n: {
name = "base0${n}";
value = mkOption {
description = "The base0${n} color to use";
type = hexColor;
apply = v:
if hasPrefix "#" v
then v
else "#${v}";
};
})
numbers;
in {
options.vim.theme = {
enable = mkOption {
type = bool;
description = "Enable theming";
};
name = mkOption {
type = enum (attrNames supportedThemes);
description = "Supported themes can be found in `supportedThemes.nix`";
description = ''
Supported themes can be found in {file}`supportedThemes.nix`.
Setting the theme to "base16" enables base16 theming and
requires all of the colors in {option}`vim.theme.base16-colors` to be set.
'';
};
base16-colors = base16Options;
style = mkOption {
type = enum supportedThemes.${cfg.name}.styles;
description = "Specific style for theme if it supports it";
};
transparent = mkOption {
type = bool;
default = false;
@ -47,7 +68,7 @@ in {
startPlugins = [cfg.name];
luaConfigRC.theme = entryBefore ["pluginConfigs"] ''
${cfg.extraConfig}
${supportedThemes.${cfg.name}.setup {inherit (cfg) style transparent;}}
${supportedThemes.${cfg.name}.setup {inherit (cfg) style transparent base16-colors;}}
'';
};
};

View file

@ -11,7 +11,7 @@
inherit (lib.nvim.dag) entryBefore entryAfter;
cfg = config.vim.treesitter;
usingNvimCmp = config.vim.autocomplete.enable && config.vim.autocomplete.type == "nvim-cmp";
usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
self = import ./treesitter.nix {inherit pkgs lib;};
mappingDefinitions = self.options.vim.treesitter.mappings;
@ -21,7 +21,7 @@ in {
vim = {
startPlugins = ["nvim-treesitter"] ++ optional usingNvimCmp "cmp-treesitter";
autocomplete.sources = {"treesitter" = "[Treesitter]";};
autocomplete.nvim-cmp.sources = {treesitter = "[Treesitter]";};
treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars;
maps = {

View file

@ -21,7 +21,7 @@ in {
mkBool true "override the lsp markdown formatter with Noice";
"cmp.entry.get_documentation" =
mkBool (config.vim.autocomplete.type == "nvim-cmp") "override cmp documentation with Noice";
mkBool config.vim.autocomplete.nvim-cmp.enable "override cmp documentation with Noice";
};
signature = {

View file

@ -3,7 +3,7 @@
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.modules) mkIf mkMerge mkDefault;
inherit (lib.nvim.binds) mkBinding;
inherit (lib.nvim.dag) entryAnywhere;
@ -37,6 +37,8 @@ in {
(mkBinding cfg.mappings.leapFromWindow "<Plug>(leap-from-window)" "Leap from window")
];
vim.binds.whichKey.register."<leader>s" = mkDefault "+Leap";
vim.pluginRC.leap-nvim = entryAnywhere ''
require('leap').opts = {
max_phase_one_targets = nil,

View file

@ -9,22 +9,22 @@ in {
leapForwardTo = mkOption {
type = nullOr str;
description = "Leap forward to";
default = "s";
default = "<leader>ss";
};
leapBackwardTo = mkOption {
type = nullOr str;
description = "Leap backward to";
default = "S";
default = "<leader>sS";
};
leapForwardTill = mkOption {
type = nullOr str;
description = "Leap forward till";
default = "x";
default = "<leader>sx";
};
leapBackwardTill = mkOption {
type = nullOr str;
description = "Leap backward till";
default = "X";
default = "<leader>sX";
};
leapFromWindow = mkOption {
type = nullOr str;

View file

@ -3,42 +3,29 @@
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetBinding;
inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.utility.surround;
self = import ./surround.nix {inherit lib config;};
mappingDefinitions = self.options.vim.utility.surround.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = [
"nvim-surround"
];
startPlugins = ["nvim-surround"];
pluginRC.surround = entryAnywhere "require('nvim-surround').setup(${toLuaObject cfg.setupOpts})";
pluginRC.surround = entryAnywhere ''
require('nvim-surround').setup()
'';
maps = {
insert = mkMerge [
(mkIf (mappings.insert != null) (mkSetBinding mappings.insert "<Plug>(nvim-surround-insert)"))
(mkIf (mappings.insertLine != null) (mkSetBinding mappings.insertLine "<Plug>(nvim-surround-insert-line)"))
];
normal = mkMerge [
(mkIf (mappings.normal != null) (mkSetBinding mappings.normal "<Plug>(nvim-surround-normal)"))
(mkIf (mappings.normalCur != null) (mkSetBinding mappings.normalCur "<Plug>(nvim-surround-normal-cur)"))
(mkIf (mappings.normalLine != null) (mkSetBinding mappings.normalLine "<Plug>(nvim-surround-normal-line)"))
(mkIf (mappings.normalCurLine != null) (mkSetBinding mappings.normalCurLine "<Plug>(nvim-surround-normal-cur-line)"))
(mkIf (mappings.delete != null) (mkSetBinding mappings.delete "<Plug>(nvim-surround-delete)"))
(mkIf (mappings.change != null) (mkSetBinding mappings.change "<Plug>(nvim-surround-change)"))
];
visualOnly = mkMerge [
(mkIf (mappings.visual != null) (mkSetBinding mappings.visual "<Plug>(nvim-surround-visual)"))
(mkIf (mappings.visualLine != null) (mkSetBinding mappings.visualLine "<Plug>(nvim-surround-visual-line)"))
];
utility.surround.setupOpts.keymaps = mkIf cfg.useVendoredKeybindings {
insert = "<C-g>z";
insert_line = "<C-g>Z";
normal = "gz";
normal_cur = "gZ";
normal_line = "gzz";
normal_cur_line = "gZZ";
visual = "gz";
visual_line = "gZ";
delete = "gzd";
change = "gzr";
change_line = "gZR";
};
};
};

View file

@ -1,90 +1,24 @@
{
lib,
config,
...
}: let
inherit (lib.modules) mkIf mkDefault;
{lib, ...}: let
inherit (lib.options) mkOption;
inherit (lib.types) bool nullOr str;
inherit (lib.types) bool;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
options.vim.utility.surround = {
enable = mkOption {
type = bool;
default = false;
description = "nvim-surround: add/change/delete surrounding delimiter pairs with ease. Note that the default mappings deviate from upstreeam to avoid conflicts with nvim-leap.";
description = ''
nvim-surround: add/change/delete surrounding delimiter pairs with ease.
Note that the default mappings deviate from upstreeam to avoid conflicts
with nvim-leap.
'';
};
setupOpts = mkPluginSetupOption "nvim-surround" {};
useVendoredKeybindings = mkOption {
type = bool;
default = true;
description = "Use alternative set of keybindings that avoids conflicts with other popular plugins, e.g. nvim-leap";
};
mappings = {
insert = mkOption {
type = nullOr str;
default = "<C-g>z";
description = "Add surround character around the cursor";
};
insertLine = mkOption {
type = nullOr str;
default = "<C-g>Z";
description = "Add surround character around the cursor on new lines";
};
normal = mkOption {
type = nullOr str;
default = "gz";
description = "Surround motion with character";
};
normalCur = mkOption {
type = nullOr str;
default = "gZ";
description = "Surround motion with character on new lines";
};
normalLine = mkOption {
type = nullOr str;
default = "gzz";
description = "Surround line with character";
};
normalCurLine = mkOption {
type = nullOr str;
default = "gZZ";
description = "Surround line with character on new lines";
};
visual = mkOption {
type = nullOr str;
default = "gz";
description = "Surround selection with character";
};
visualLine = mkOption {
type = nullOr str;
default = "gZ";
description = "Surround selection with character on new lines";
};
delete = mkOption {
type = nullOr str;
default = "gzd";
description = "Delete surrounding character";
};
change = mkOption {
type = nullOr str;
default = "gzr";
description = "Change surrounding character";
};
};
};
config.vim.utility.surround = let
cfg = config.vim.utility.surround;
in {
mappings = mkIf (! cfg.useVendoredKeybindings) (mkDefault {
insert = null;
insertLine = null;
normal = null;
normalCur = null;
normalLine = null;
normalCurLine = null;
visual = null;
visualLine = null;
delete = null;
change = null;
});
};
}

View file

@ -4,80 +4,14 @@
...
}: let
inherit (builtins) map mapAttrs filter;
inherit (lib.options) mkOption;
inherit (lib.attrsets) mapAttrsToList filterAttrs getAttrs attrValues attrNames;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatLines concatMapStringsSep;
inherit (lib.trivial) showWarnings;
inherit (lib.types) str nullOr;
inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAfter mkLuarcSection resolveDag entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.config) mkBool;
cfg = config.vim;
# Most of the keybindings code is highly inspired by pta2002/nixvim.
# Thank you!
mapConfigOptions = {
silent =
mkBool false
"Whether this mapping should be silent. Equivalent to adding <silent> to a map.";
nowait =
mkBool false
"Whether to wait for extra input on ambiguous mappings. Equivalent to adding <nowait> to a map.";
script =
mkBool false
"Equivalent to adding <script> to a map.";
expr =
mkBool false
"Means that the action is actually an expression. Equivalent to adding <expr> to a map.";
unique =
mkBool false
"Whether to fail if the map is already defined. Equivalent to adding <unique> to a map.";
noremap =
mkBool true
"Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default.";
desc = mkOption {
type = nullOr str;
default = null;
description = "A description of this keybind, to be shown in which-key, if you have it enabled.";
};
};
genMaps = mode: maps: let
/*
Take a user-defined action (string or attrs) and return the following attribute set:
{
action = (string) the actual action to map to this key
config = (attrs) the configuration options for this mapping (noremap, silent...)
}
*/
normalizeAction = action: {
# Extract the values of the config options that have been explicitly set by the user
config =
filterAttrs (_: v: v != null)
(getAttrs (attrNames mapConfigOptions) action);
action =
if action.lua
then mkLuaInline action.action
else action.action;
};
in
attrValues (mapAttrs
(key: action: let
normalizedAction = normalizeAction action;
in {
inherit (normalizedAction) action config;
inherit key;
inherit mode;
})
maps);
in {
config = let
globalsScript =
@ -98,38 +32,18 @@ in {
mapResult = result: concatLines (map mkLuarcSection result);
};
toLuaBindings = mode: maps:
map (value: ''
vim.keymap.set(${toLuaObject mode}, ${toLuaObject value.key}, ${toLuaObject value.action}, ${toLuaObject value.config})
'') (genMaps mode maps);
getAction = keymap:
if keymap.lua
then mkLuaInline keymap.action
else keymap.action;
# I'm not sure if every one of these will work.
allmap = toLuaBindings "" config.vim.maps.normalVisualOp;
nmap = toLuaBindings "n" config.vim.maps.normal;
vmap = toLuaBindings "v" config.vim.maps.visual;
xmap = toLuaBindings "x" config.vim.maps.visualOnly;
smap = toLuaBindings "s" config.vim.maps.select;
imap = toLuaBindings "i" config.vim.maps.insert;
cmap = toLuaBindings "c" config.vim.maps.command;
tmap = toLuaBindings "t" config.vim.maps.terminal;
lmap = toLuaBindings "l" config.vim.maps.lang;
omap = toLuaBindings "o" config.vim.maps.operator;
icmap = toLuaBindings "ic" config.vim.maps.insertCommand;
getOpts = keymap: {
inherit (keymap) desc silent nowait script expr unique noremap;
};
maps = [
nmap
imap
vmap
xmap
smap
cmap
omap
tmap
lmap
icmap
allmap
];
mappings = concatLines (map concatLines maps);
toLuaKeymap = bind: "vim.keymap.set(${toLuaObject bind.mode}, ${toLuaObject bind.key}, ${toLuaObject (getAction bind)}, ${toLuaObject (getOpts bind)})";
keymaps = concatLines (map toLuaKeymap cfg.keymaps);
in {
vim = {
luaConfigRC = {
@ -140,7 +54,7 @@ in {
# Basic
pluginConfigs = entryAfter ["optionsScript"] pluginConfigs;
extraPluginConfigs = entryAfter ["pluginConfigs"] extraPluginConfigs;
mappings = entryAfter ["extraPluginConfigs"] mappings;
mappings = entryAfter ["extraPluginConfigs"] keymaps;
};
builtLuaConfigRC = let

View file

@ -3,27 +3,18 @@
lib,
...
}: let
inherit (lib.modules) mkRemovedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalMD literalExpression;
inherit (lib.strings) optionalString;
inherit (lib.types) str attrs lines listOf either path bool;
inherit (lib.types) str attrs lines listOf either path;
inherit (lib.nvim.types) dagOf;
inherit (lib.nvim.lua) listToLuaTable;
cfg = config.vim;
in {
imports = [
(mkRemovedOptionModule ["vim" "configRC"] ''
Please migrate your configRC sections to Neovim's Lua format, and
add them to luaConfigRC.
See the v0.7 release notes for more information on how to migrate
your existing configurations.
'')
];
options.vim = {
enableLuaLoader = mkEnableOption ''
[{option}`official documentation`]: https://neovim.io/doc/user/lua.html#vim.loader.enable()
the experimental Lua module loader to speed up the start up process
If `true`, this will enable the experimental Lua module loader which:
@ -32,29 +23,11 @@ in {
- adds the libs loader
- removes the default Neovim loader
This is disabled by default. Before setting this option, please
take a look at the [{option}`official documentation`](https://neovim.io/doc/user/lua.html#vim.loader.enable()).
'';
disableDefaultRuntimePaths = mkOption {
type = bool;
default = true;
example = false;
description = ''
Disables the default runtime paths that are set by Neovim
when it starts up. This is useful when you want to have
full control over the runtime paths that are set by Neovim.
::: {.note}
To avoid leaking imperative user configuration into your
configuration, this is enabled by default. If you wish
to load configuration from user configuration directories
(e.g. {file}`$HOME/.config/nvim`, {file}`$HOME/.config/nvim/after`
and {file}`$HOME/.local/share/nvim/site`) you may set this
option to true.
This is disabled by default. Before setting this option, please
take a look at the [{option}`official documentation`].
:::
'';
};
additionalRuntimePaths = mkOption {
type = listOf (either path str);
@ -180,21 +153,6 @@ in {
vim.opt.runtimepath:append(${listToLuaTable cfg.additionalRuntimePaths})
''}
${optionalString cfg.disableDefaultRuntimePaths ''
-- Remove default user runtime paths from the
-- `runtimepath` option to avoid leaking user configuration
-- into the final neovim wrapper
local defaultRuntimePaths = {
vim.fn.stdpath('config'), -- $HOME/.config/nvim
vim.fn.stdpath('config') .. "/after", -- $HOME/.config/nvim/after
vim.fn.stdpath('data') .. "/site", -- $HOME/.local/share/nvim/site
}
for _, path in ipairs(defaultRuntimePaths) do
vim.opt.runtimepath:remove(path)
end
''}
${optionalString cfg.enableLuaLoader "vim.loader.enable()"}
'';