Compare commits

...

13 commits

Author SHA1 Message Date
Soliprem
2e1134806a
Merge b321c01047 into 57067e85ed 2024-11-08 10:16:32 +00:00
57067e85ed flake: rename input for nvim-scrollbar 2024-11-08 10:15:23 +00:00
1b16c6b19f tabline/nvim-bufferline: remove assertion; enable nvim-web-devicons by default 2024-11-08 10:15:23 +00:00
a6bb6e1b3e modules/visuals: migrate plugins to setupOpts 2024-11-08 10:15:23 +00:00
raf
b3f51048db
Merge branch 'main' into v0.7 2024-11-08 09:33:15 +00:00
Noire
8997e62b3b
utility/precognition: init module (#437)
Some checks failed
Set up binary cache / cachix (default) (push) Has been cancelled
Set up binary cache / cachix (maximal) (push) Has been cancelled
Set up binary cache / cachix (nix) (push) Has been cancelled
Validate flake & check documentation / Validate Flake Documentation (docs) (push) Has been cancelled
Validate flake & check documentation / Validate Flake Documentation (docs-html) (push) Has been cancelled
Validate flake & check documentation / Validate Flake Documentation (docs-json) (push) Has been cancelled
Validate flake & check documentation / Validate Flake Documentation (docs-manpages) (push) Has been cancelled
Validate flake & check formatting / Validate Flake (push) Has been cancelled
Validate flake & check formatting / Formatting via Alejandra (push) Has been cancelled
Build and deploy documentation / Check latest commit (push) Has been cancelled
Build and deploy documentation / publish (push) Has been cancelled
* utility/precognition: init

* utility/precognition: fix priority example, add default

* utility/precognition: add files to default.nix

* utility/precognition: fix typos, manual fmt

* utility/precognition: remove useless mappings

i was going to add binds to toggle/enable/disable but ehhh
idk

* utility/precognition: fix hints option

it broke

* utility/precognition: update gutter hints, new description

* utility/precognition: add files to motion defaults

* utility/precognition: add plugin to flake

* utility/precognition: remove comment reference

oops

* utility/precognition: add precognition to maximal configuration

it does work!

* utility/precognition: update descriptions

needs docs link, desc is somewhat obscure.

* docs: add credit to release notes

* utility/precognition: format

* utility/precognition: de-linkify descriptions

* utility/precognition: no more rec

* utility/precognition: convert to setupOpts

honestly raf was cooking with this one.
it's much nicer to use compared to interpolation lol

* utility/precognition: remove unnecessary function parameter

* utility/precognition: format

* utility/precognition: add description to disabled_fts

oops

* utility/precognition: manual format

* utility/precognition: remove periods at the end of descriptions

* utility/precognition: fix configuration.nix entry

oops lol

* utility/precognition: format

* utility/precognition: expand `vim`

* precognition: consistency changes

Just my minor nits.

---------

Co-authored-by: NotAShelf <raf@notashelf.dev>
2024-11-08 09:32:02 +00:00
82c2d4bdd0
flake/packages: rename deprecated xdg_utils 2024-11-08 12:30:39 +03:00
1badee81db
flake: bump nixpkgs 2024-11-08 12:08:12 +03:00
383924d225
meta: update release info 2024-11-07 11:12:38 +03:00
81eda5b340
neovim/spellcheck: add autogroup to spellcheck fts autocmd; fix vim-dirtytalk 2024-11-06 19:33:08 +03:00
f429379e34
docs: update release notes 2024-11-06 19:33:06 +03:00
688bb8d9ba
spellcheck: allow adding arbitrary spellfiles from name-value pairs 2024-11-06 19:32:58 +03:00
Ching Pei Yang
21fcace3ed
treewide: implement lazy loading via lz.n for selected plugins (#407)
* flake: add lz.n and lzn-auto-require

* lazy: init module

* lzn-auto-require: add init lua code

* wrapper: fix opt plugin format

* lib.binds: add lz.n variant of bind functions

* telescope: lazy load

* nvim-tree: lazy load

* dapui: lazy load

* trouble: lazy load

* toggleterm: lazy load

* cheatsheet: lazy load

* diffview: lazy load

* icon-picker: lazy load

* leap: lazy load

* fidget: lazy load

* docs: add section on lazy plugins

* lazy: support lazy.enable=false

* comment-nvim: lazy load

* surround-nvim: lazy load

* neo-tree: lazy load

* fixup! lazy: init module

* dap: appease the nix gods (fix statix lint)

* flake.lock: fix merge mistake

* doc: update release note

* fixup! doc: update release note

* neo-tree: fix duplicate neo-tree install

* lazy: use attrsOf for lazy.plugins

* treewide: update lazy.plugins syntax

* docs: update lazy.plugins syntax

* lazy: cleanup

* Update docs/manual/hacking/additional-plugins.md

Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>

* formatting nitpick

Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>

* typo tee hee :3

Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>

* typo tee hee :4

Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>

* flake: update lz.n

* lazy: update lz.n plugin spec

* lazy: allow lines in place of str for lua code

* copilot: lazy load

* cmp: lazy load

this moves cmp itself to lazy.plugins but other plugins that call cmp
are not yet lazy so cmp is technically not yet lazy

* luasnip: lazy load

* flake: add rtp.nvim

* cmp: actually lazy load source

* fixup! cmp: actually lazy load source

* format

* docs: fix broken link

* cmp-nvim-lsp: lazy load

* lazy: allow key mode of str type

* cmp: install sourcess via cmp.sourcePlugins

* Update docs/manual/hacking/additional-plugins.md

Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>

* lazy: refactor common var

* nvim-dap-ui: add setupOpts

* refactor: re-order plugin and lz.n configs

lazy: make lzn-auto-require togglable

* docs: update dag-entries

* trouble: remove redundant import

* lazy: remove unused module arg

* toggleterm: make lazygit keybind optional

* toggleterm: use toLuaObject for clarity

* surround: rework keymap config

* remove stale FIXME

* lsp: use cmp_nvim_lsp capabilities

* cmp: deduplicate attr key

* theme: ensure themes load before lazy plugins

* doc: update description of `theme` dag entry

* lsp: avoid loading cmp on startup

* doc: update configuration docs on custom plugins

* cmp: skip trigger_load if lazy disabled

* treesitter: remove redundant code

* lsp: mark hack as HACK

* comment: remove redundant plugin

* Squash merge v0.7 into feature/lzn

---------

Co-authored-by: raf <raf@notashelf.dev>
Co-authored-by: diniamo <55629891+diniamo@users.noreply.github.com>
2024-11-04 16:50:50 +01:00
79 changed files with 2205 additions and 968 deletions

View file

@ -77,20 +77,17 @@ isMaximal: {
}; };
visuals = { visuals = {
enable = true; nvim-scrollbar.enable = isMaximal;
nvimWebDevicons.enable = true; nvim-web-devicons.enable = true;
scrollBar.enable = isMaximal; nvim-cursorline.enable = true;
smoothScroll.enable = true; cinnamon-nvim.enable = true;
cellularAutomaton.enable = false;
fidget-nvim.enable = true; fidget-nvim.enable = true;
highlight-undo.enable = true; highlight-undo.enable = true;
indent-blankline.enable = true;
indentBlankline.enable = true; # Fun
cellular-automaton.enable = false;
cursorline = {
enable = true;
lineTimeout = 0;
};
}; };
statusline = { statusline = {
@ -164,6 +161,7 @@ isMaximal: {
motion = { motion = {
hop.enable = true; hop.enable = true;
leap.enable = true; leap.enable = true;
precognition.enable = isMaximal;
}; };
images = { images = {

View file

@ -20,6 +20,7 @@ custom plugins that you might have added to your configuration.
```{=include=} sections ```{=include=} sections
custom-plugins/configuring.md custom-plugins/configuring.md
custom-plugins/new-method.md custom-plugins/lazy-method.md
custom-plugins/old-method.md custom-plugins/non-lazy-method.md
custom-plugins/legacy-method.md
``` ```

View file

@ -1,12 +1,32 @@
# Configuring {#sec-configuring-plugins} # Configuring {#sec-configuring-plugins}
Just making the plugin to your Neovim configuration available might not always Just making the plugin to your Neovim configuration available might not always be enough. In that
be enough. In that case, you can write custom lua config using either case, you can write custom lua config using either `config.vim.lazy.plugins.*.setupOpts`
`config.vim.extraPlugins` (which has the `setup` field) or `config.vim.extraPlugins.*.setup` or `config.vim.luaConfigRC`.
`config.vim.luaConfigRC`. The first option uses an attribute set, which maps DAG
section names to a custom type, which has the fields `package`, `after`, The first option uses an extended version of `lz.n`'s PluginSpec. `setupModule` and `setupOpt` can
`setup`. They allow you to set the package of the plugin, the sections its setup be used if the plugin uses a `require('module').setup(...)` pattern. Otherwise, the `before` and
code should be after (note that the `extraPlugins` option has its own DAG `after` hooks should do what you need.
```nix
{
config.vim.lazy.plugins = {
aerial-nvim = {
# ^^^^^^^^^ this name should match the package.pname or package.name
package = aerial-nvim;
setupModule = "aerial";
setupOpts = {option_name = false;};
after = "print('aerial loaded')";
};
};
}
```
The second option uses an attribute set, which maps DAG section names to a custom type, which has
the fields `package`, `after`, `setup`. They allow you to set the package of the plugin, the
sections its setup code should be after (note that the `extraPlugins` option has its own DAG
scope), and the its setup code respectively. For example: scope), and the its setup code respectively. For example:
```nix ```nix
@ -24,7 +44,7 @@ config.vim.extraPlugins = with pkgs.vimPlugins; {
} }
``` ```
The second option also uses an attribute set, but this one is resolved as a DAG The third option also uses an attribute set, but this one is resolved as a DAG
directly. The attribute names denote the section names, and the values lua code. directly. The attribute names denote the section names, and the values lua code.
For example: For example:

View file

@ -0,0 +1,40 @@
# Lazy Method {#sec-lazy-method}
As of version **0.7**, we exposed an API for configuring lazy-loaded plugins via
`lz.n` and `lzn-auto-require`.
```nix
{
config.vim.lazy.plugins = {
aerial = {
package = pkgs.vimPlugins.aerial-nvim;
setupModule = aerial;
setupOpts = {
option_name = true;
};
after = ''
-- custom lua code to run after plugin is loaded
print('aerial loaded')
'';
# Explicitly mark plugin as lazy. You don't need this if you define one of
# the trigger "events" below
lazy = true;
# load on command
cmd = ["AerialOpen"];
# load on event
event = ["BufEnter"];
# load on keymap
keys = [
{
key = "<leader>a";
action = ":AerialToggle<CR>";
}
];
};
};
}
```

View file

@ -1,4 +1,4 @@
# Old Method {#sec-old-method} # Legacy Method {#sec-legacy-method}
Prior to version 0.5, the method of adding new plugins was adding the plugin Prior to version 0.5, the method of adding new plugins was adding the plugin
package to `vim.startPlugins` and add its configuration as a DAG under one of package to `vim.startPlugins` and add its configuration as a DAG under one of

View file

@ -1,4 +1,4 @@
# New Method {#sec-new-method} # Non-lazy Method {#sec-non-lazy-method}
As of version **0.5**, we have a more extensive API for configuring plugins, As of version **0.5**, we have a more extensive API for configuring plugins,
under `vim.extraPlugins`. Instead of using DAGs exposed by the library, you may under `vim.extraPlugins`. Instead of using DAGs exposed by the library, you may

View file

@ -12,12 +12,14 @@ entries in nvf:
2. `globalsScript` - used to set globals defined in `vim.globals` 2. `globalsScript` - used to set globals defined in `vim.globals`
3. `basic` - used to set basic configuration options 3. `basic` - used to set basic configuration options
4. `optionsScript` - used to set options defined in `vim.o` 4. `optionsScript` - used to set options defined in `vim.o`
5. `theme` (this is simply placed before `pluginConfigs`, meaning that 5. `theme` (this is simply placed before `pluginConfigs` and `lazyConfigs`, meaning that
surrounding entries don't depend on it) - used to set up the theme, which has surrounding entries don't depend on it) - used to set up the theme, which has to be done before
to be done before other plugins other plugins
6. `pluginConfigs` - the result of the nested `vim.pluginRC` (internal option, 6. `lazyConfigs` - `lz.n` and `lzn-auto-require` configs. If `vim.lazy.enable`
is false, this will contain each plugin's config instead.
7. `pluginConfigs` - the result of the nested `vim.pluginRC` (internal option,
see the [Custom Plugins](/index.xhtml#ch-custom-plugins) page for adding your see the [Custom Plugins](/index.xhtml#ch-custom-plugins) page for adding your
own plugins) DAG, used to set up internal plugins own plugins) DAG, used to set up internal plugins
7. `extraPluginConfigs` - the result of `vim.extraPlugins`, which is not a 8. `extraPluginConfigs` - the result of `vim.extraPlugins`, which is not a
direct DAG, but is converted to, and resolved as one internally direct DAG, but is converted to, and resolved as one internally
8. `mappings` - the result of `vim.maps` 9. `mappings` - the result of `vim.maps`

View file

@ -124,3 +124,61 @@ vim.your-plugin.setupOpts = {
''; '';
} }
``` ```
## Lazy plugins {#sec-lazy-plugins}
If the plugin can be lazy-loaded, `vim.lazy.plugins` should be used to add it. Lazy
plugins are managed by `lz.n`.
```nix
# in modules/.../your-plugin/config.nix
{lib, config, ...}:
let
cfg = config.vim.your-plugin;
in {
vim.lazy.plugins.your-plugin = {
# instead of vim.startPlugins, use this:
package = "your-plugin";
# if your plugin uses the `require('your-plugin').setup{...}` pattern
setupModule = "your-plugin";
inherit (cfg) setupOpts;
# events that trigger this plugin to be loaded
event = ["DirChanged"];
cmd = ["YourPluginCommand"];
# keymaps
keys = [
# we'll cover this in detail in the keymaps section
{
key = "<leader>d";
mode = "n";
action = ":YourPluginCommand";
}
];
};
;
}
```
This results in the following lua code:
```lua
require('lz.n').load({
{
"name-of-your-plugin",
after = function()
require('your-plugin').setup({--[[ your setupOpts ]]})
end,
event = {"DirChanged"},
cmd = {"YourPluginCommand"},
keys = {
{"<leader>d", ":YourPluginCommand", mode = {"n"}},
},
}
})
```
A full list of options can be found
[here](https://notashelf.github.io/nvf/options.html#opt-vim.lazy.plugins

View file

@ -123,6 +123,10 @@ To migrate to `nixfmt`, simply change `vim.languages.nix.format.type` to
recommended to go through rustacean.nvim's README to take a closer look at its recommended to go through rustacean.nvim's README to take a closer look at its
features and usage features and usage
- Add [lz.n] support and lazy-load some builtin plugins.
[lz.n]: https://github.com/mrcjkb/lz.n
[jacekpoz](https://jacekpoz.pl): [jacekpoz](https://jacekpoz.pl):
[ocaml-lsp]: https://github.com/ocaml/ocaml-lsp [ocaml-lsp]: https://github.com/ocaml/ocaml-lsp
@ -181,6 +185,7 @@ To migrate to `nixfmt`, simply change `vim.languages.nix.format.type` to
default. default.
- Refactor of `nvim-cmp` and completion related modules - Refactor of `nvim-cmp` and completion related modules
- Remove `autocomplete.type` in favor of per-plugin enable options such as - Remove `autocomplete.type` in favor of per-plugin enable options such as
[](#opt-vim.autocomplete.nvim-cmp.enable). [](#opt-vim.autocomplete.nvim-cmp.enable).
- Deprecate legacy Vimsnip in favor of Luasnip, and integrate - Deprecate legacy Vimsnip in favor of Luasnip, and integrate
@ -273,9 +278,13 @@ To migrate to `nixfmt`, simply change `vim.languages.nix.format.type` to
configuration for [dashboard.nvim](https://github.com/nvimdev/dashboard-nvim) configuration for [dashboard.nvim](https://github.com/nvimdev/dashboard-nvim)
- Update `lualine.nvim` input and add missing themes: - Update `lualine.nvim` input and add missing themes:
- Adds `ayu`, `gruvbox_dark`, `iceberg`, `moonfly`, `onedark`, - Adds `ayu`, `gruvbox_dark`, `iceberg`, `moonfly`, `onedark`,
`powerline_dark` and `solarized_light` themes. `powerline_dark` and `solarized_light` themes.
- Add [](#opt-vim.spellcheck.extraSpellWords) to allow adding arbitrary
spellfiles to Neovim's runtime with ease.
[ppenguin](https://github.com/ppenguin): [ppenguin](https://github.com/ppenguin):
- Telescope: - Telescope:
@ -314,3 +323,8 @@ To migrate to `nixfmt`, simply change `vim.languages.nix.format.type` to
[](#opt-vim.languages.svelte.format.type) respectively. [](#opt-vim.languages.svelte.format.type) respectively.
- Replace [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) with - Replace [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) with
[nixfmt](https://github.com/NixOS/nixfmt) (nixfmt-rfc-style). [nixfmt](https://github.com/NixOS/nixfmt) (nixfmt-rfc-style).
[Nowaaru](https://github.com/Nowaaru):
- Add `precognition-nvim`.

View file

@ -98,11 +98,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1726871744, "lastModified": 1730958623,
"narHash": "sha256-V5LpfdHyQkUF7RfOaDPrZDP+oqz88lTJrMT1+stXNwo=", "narHash": "sha256-JwQZIGSYnRNOgDDoIgqKITrPVil+RMWHsZH1eE1VGN0=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a1d92660c6b3b7c26fb883500a80ea9d33321be2", "rev": "85f7e662eda4fa3a995556527c87b2524b691933",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -892,6 +892,39 @@
"type": "github" "type": "github"
} }
}, },
"plugin-lz-n": {
"flake": false,
"locked": {
"lastModified": 1729525284,
"narHash": "sha256-fk+ejqcqqOQz3q4D3VB2Q+U/6wCpCDk1tiDMp2YrPNE=",
"owner": "nvim-neorocks",
"repo": "lz.n",
"rev": "ffd9991400ba7137f4fa8560ff50bccd7f8fb3ee",
"type": "github"
},
"original": {
"owner": "nvim-neorocks",
"repo": "lz.n",
"type": "github"
}
},
"plugin-lzn-auto-require": {
"flake": false,
"locked": {
"lastModified": 1727636949,
"narHash": "sha256-BAOzN+XOrFAJwHmsF8JtZ2EyjP9283FD/I2TbFqGSEw=",
"owner": "horriblename",
"repo": "lzn-auto-require",
"rev": "55ecd60831dac8c01d6f3dcb63a30a63a1690eb8",
"type": "github"
},
"original": {
"owner": "horriblename",
"ref": "require-rewrite",
"repo": "lzn-auto-require",
"type": "github"
}
},
"plugin-mind-nvim": { "plugin-mind-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1357,6 +1390,22 @@
"type": "github" "type": "github"
} }
}, },
"plugin-nvim-scrollbar": {
"flake": false,
"locked": {
"lastModified": 1729162132,
"narHash": "sha256-/nB7eP2Rz/A9zMXrNEH4FReo6eZS0C/SEGvKhxV7AUA=",
"owner": "petertriho",
"repo": "nvim-scrollbar",
"rev": "6994eb9f73d5fdc36ee2c8717940e8c853e51a49",
"type": "github"
},
"original": {
"owner": "petertriho",
"repo": "nvim-scrollbar",
"type": "github"
}
},
"plugin-nvim-session-manager": { "plugin-nvim-session-manager": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1581,6 +1630,22 @@
"type": "github" "type": "github"
} }
}, },
"plugin-precognition-nvim": {
"flake": false,
"locked": {
"lastModified": 1730325090,
"narHash": "sha256-onY1Aa+dwLR1wRua52hpSXj6zZOZXjkUlDjDa0xEEcE=",
"owner": "tris203",
"repo": "precognition.nvim",
"rev": "0189e8d6f96275a079b2805d68d49414871885cd",
"type": "github"
},
"original": {
"owner": "tris203",
"repo": "precognition.nvim",
"type": "github"
}
},
"plugin-project-nvim": { "plugin-project-nvim": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1629,6 +1694,22 @@
"type": "github" "type": "github"
} }
}, },
"plugin-rtp-nvim": {
"flake": false,
"locked": {
"lastModified": 1724409589,
"narHash": "sha256-lmJbiD7I7MTEEpukESs67uAmLyn+p66hrUKLbEHp0Kw=",
"owner": "nvim-neorocks",
"repo": "rtp.nvim",
"rev": "494ddfc888bb466555d90ace731856de1320fe45",
"type": "github"
},
"original": {
"owner": "nvim-neorocks",
"repo": "rtp.nvim",
"type": "github"
}
},
"plugin-rustaceanvim": { "plugin-rustaceanvim": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1645,22 +1726,6 @@
"type": "github" "type": "github"
} }
}, },
"plugin-scrollbar-nvim": {
"flake": false,
"locked": {
"lastModified": 1684886154,
"narHash": "sha256-zLBexSxQCn9HPY04a9w/UCJP1F5ShI2X12I9xE9H0cM=",
"owner": "petertriho",
"repo": "nvim-scrollbar",
"rev": "35f99d559041c7c0eff3a41f9093581ceea534e8",
"type": "github"
},
"original": {
"owner": "petertriho",
"repo": "nvim-scrollbar",
"type": "github"
}
},
"plugin-smartcolumn": { "plugin-smartcolumn": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1991,6 +2056,8 @@
"plugin-lua-utils-nvim": "plugin-lua-utils-nvim", "plugin-lua-utils-nvim": "plugin-lua-utils-nvim",
"plugin-lualine": "plugin-lualine", "plugin-lualine": "plugin-lualine",
"plugin-luasnip": "plugin-luasnip", "plugin-luasnip": "plugin-luasnip",
"plugin-lz-n": "plugin-lz-n",
"plugin-lzn-auto-require": "plugin-lzn-auto-require",
"plugin-mind-nvim": "plugin-mind-nvim", "plugin-mind-nvim": "plugin-mind-nvim",
"plugin-minimap-vim": "plugin-minimap-vim", "plugin-minimap-vim": "plugin-minimap-vim",
"plugin-modes-nvim": "plugin-modes-nvim", "plugin-modes-nvim": "plugin-modes-nvim",
@ -2020,6 +2087,7 @@
"plugin-nvim-neoclip": "plugin-nvim-neoclip", "plugin-nvim-neoclip": "plugin-nvim-neoclip",
"plugin-nvim-nio": "plugin-nvim-nio", "plugin-nvim-nio": "plugin-nvim-nio",
"plugin-nvim-notify": "plugin-nvim-notify", "plugin-nvim-notify": "plugin-nvim-notify",
"plugin-nvim-scrollbar": "plugin-nvim-scrollbar",
"plugin-nvim-session-manager": "plugin-nvim-session-manager", "plugin-nvim-session-manager": "plugin-nvim-session-manager",
"plugin-nvim-surround": "plugin-nvim-surround", "plugin-nvim-surround": "plugin-nvim-surround",
"plugin-nvim-tree-lua": "plugin-nvim-tree-lua", "plugin-nvim-tree-lua": "plugin-nvim-tree-lua",
@ -2034,11 +2102,12 @@
"plugin-oxocarbon": "plugin-oxocarbon", "plugin-oxocarbon": "plugin-oxocarbon",
"plugin-pathlib-nvim": "plugin-pathlib-nvim", "plugin-pathlib-nvim": "plugin-pathlib-nvim",
"plugin-plenary-nvim": "plugin-plenary-nvim", "plugin-plenary-nvim": "plugin-plenary-nvim",
"plugin-precognition-nvim": "plugin-precognition-nvim",
"plugin-project-nvim": "plugin-project-nvim", "plugin-project-nvim": "plugin-project-nvim",
"plugin-registers": "plugin-registers", "plugin-registers": "plugin-registers",
"plugin-rose-pine": "plugin-rose-pine", "plugin-rose-pine": "plugin-rose-pine",
"plugin-rtp-nvim": "plugin-rtp-nvim",
"plugin-rustaceanvim": "plugin-rustaceanvim", "plugin-rustaceanvim": "plugin-rustaceanvim",
"plugin-scrollbar-nvim": "plugin-scrollbar-nvim",
"plugin-smartcolumn": "plugin-smartcolumn", "plugin-smartcolumn": "plugin-smartcolumn",
"plugin-sqls-nvim": "plugin-sqls-nvim", "plugin-sqls-nvim": "plugin-sqls-nvim",
"plugin-tabular": "plugin-tabular", "plugin-tabular": "plugin-tabular",

View file

@ -113,6 +113,22 @@
}; };
## Plugins ## Plugins
# Lazy loading
plugin-lz-n = {
url = "github:nvim-neorocks/lz.n";
flake = false;
};
plugin-lzn-auto-require = {
url = "github:horriblename/lzn-auto-require/require-rewrite";
flake = false;
};
plugin-rtp-nvim = {
url = "github:nvim-neorocks/rtp.nvim";
flake = false;
};
# LSP plugins # LSP plugins
plugin-nvim-lspconfig = { plugin-nvim-lspconfig = {
url = "github:neovim/nvim-lspconfig"; url = "github:neovim/nvim-lspconfig";
@ -427,7 +443,7 @@
flake = false; flake = false;
}; };
plugin-scrollbar-nvim = { plugin-nvim-scrollbar = {
url = "github:petertriho/nvim-scrollbar"; url = "github:petertriho/nvim-scrollbar";
flake = false; flake = false;
}; };
@ -550,6 +566,11 @@
flake = false; flake = false;
}; };
plugin-precognition-nvim = {
url = "github:tris203/precognition.nvim";
flake = false;
};
# Note-taking # Note-taking
plugin-obsidian-nvim = { plugin-obsidian-nvim = {
url = "github:epwalsh/obsidian.nvim"; url = "github:epwalsh/obsidian.nvim";

View file

@ -19,7 +19,7 @@
docs-html-wrapped = pkgs.writeScriptBin "docs-html-wrapped" '' docs-html-wrapped = pkgs.writeScriptBin "docs-html-wrapped" ''
#!${pkgs.stdenv.shell} #!${pkgs.stdenv.shell}
# use xdg-open to open the docs in the browser # use xdg-open to open the docs in the browser
${pkgs.xdg_utils}/bin/xdg-open ${docs.manual.html} ${pkgs.xdg-utils}/bin/xdg-open ${docs.manual.html}
''; '';
# Exposed neovim configurations # Exposed neovim configurations
@ -29,10 +29,10 @@
# Published docker images # Published docker images
docker-nix = let docker-nix = let
inherit (pkgs) bash gitFull buildEnv dockerTools; inherit (pkgs) bash gitFull buildEnv;
inherit (config.legacyPackages) neovim-nix; inherit (config.legacyPackages) neovim-nix;
in in
dockerTools.buildImage { pkgs.dockerTools.buildImage {
name = "nvf"; name = "nvf";
tag = "latest"; tag = "latest";

View file

@ -67,6 +67,30 @@
mkLuaBinding binding.value action binding.description; mkLuaBinding binding.value action binding.description;
pushDownDefault = attr: mapAttrs (_: mkDefault) attr; pushDownDefault = attr: mapAttrs (_: mkDefault) attr;
mkLznBinding = mode: key: action: desc: {
inherit mode desc key action;
};
mkLznExprBinding = mode: key: action: desc: {
inherit mode desc key action;
lua = true;
silent = true;
expr = true;
};
mkSetLznBinding = binding: action: {
inherit action;
key = binding.value;
desc = binding.description;
};
mkSetLuaLznBinding = binding: action: {
inherit action;
key = binding.value;
lua = true;
desc = binding.description;
};
}; };
in in
binds binds

View file

@ -84,10 +84,7 @@
# built (or "normalized") plugins that are modified # built (or "normalized") plugins that are modified
builtStartPlugins = buildConfigPlugins vimOptions.startPlugins; builtStartPlugins = buildConfigPlugins vimOptions.startPlugins;
builtOptPlugins = map (package: { builtOptPlugins = map (package: package // {optional = true;}) (buildConfigPlugins vimOptions.optPlugins);
plugin = package;
optional = true;
}) (buildConfigPlugins vimOptions.optPlugins);
# additional Lua and Python3 packages, mapped to their respective functions # additional Lua and Python3 packages, mapped to their respective functions
# to conform to the format mnw expects. end user should # to conform to the format mnw expects. end user should

View file

@ -50,6 +50,7 @@
"build" "build"
"rc" "rc"
"warnings" "warnings"
"lazy"
]; ];
# Extra modules, such as deprecation warnings # Extra modules, such as deprecation warnings

View file

@ -1,11 +1,14 @@
{ {
config, config,
pkgs,
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf mkRenamedOptionModule; inherit (lib.modules) mkIf mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalExpression; inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) listOf str; inherit (lib.strings) concatLines;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.types) listOf str attrsOf;
inherit (lib.nvim.lua) listToLuaTable; inherit (lib.nvim.lua) listToLuaTable;
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
@ -24,10 +27,48 @@ in {
description = '' description = ''
A list of languages that should be used for spellchecking. A list of languages that should be used for spellchecking.
To add your own language files, you may place your `spell` To add your own language files, you may place your `spell` directory in either
directory in either `~/.config/nvim` or the {file}`$XDG_CONFIG_HOME/nvf` or in a path that is included in the
[additionalRuntimePaths](#opt-vim.additionalRuntimePaths) [additionalRuntimePaths](#opt-vim.additionalRuntimePaths) list provided by nvf.
directory provided by **nvf**. '';
};
extraSpellWords = mkOption {
type = attrsOf (listOf str);
default = {};
example = literalExpression ''{"en.utf-8" = ["nvf" "word_you_want_to_add"];}'';
description = ''
Additional words to be used for spellchecking. The names of each key will be
used as the language code for the spell file. For example
```nix
"en.utf-8" = [ ... ];
```
will result in `en.utf-8.add.spl` being added to Neovim's runtime in the
{file}`spell` directory.
::: {.warning}
The attribute keys must be in `"<name>.<encoding>"` format for Neovim to
compile your spellfiles without mangling the resulting file names. Please
make sure that you enter the correct value, as nvf does not do any kind of
internal checking. Please see {command}`:help mkspell` for more details.
Example:
```nix
# "en" is the name, and "utf-8" is the encoding. For most use cases, utf-8
# will be enough, however, you may change it to any encoding format Neovim
# accepts, e.g., utf-16.
"en.utf-8" = ["nvf" "word_you_want_to_add"];
=> $out/spell/en-utf-8.add.spl
```
:::
Note that while adding a new language, you will still need to add the name of
the language (e.g. "en") to the {option}`vim.spellcheck.languages` list by name
in order to enable spellchecking for the language. By default only `"en"` is in
the list.
''; '';
}; };
@ -38,38 +79,75 @@ in {
description = '' description = ''
A list of filetypes for which spellchecking will be disabled. A list of filetypes for which spellchecking will be disabled.
You may use `echo &filetype` in Neovim to find out the ::: {.tip}
You may use {command}`:echo &filetype` in Neovim to find out the
filetype for a specific buffer. filetype for a specific buffer.
:::
''; '';
}; };
/*
# FIXME: This needs to be revisited. It tries to install
# the spellfile to an user directory, but it cannot do so
# as we sanitize runtime paths.
programmingWordlist.enable = mkEnableOption '' programmingWordlist.enable = mkEnableOption ''
vim-dirtytalk, a wordlist for programmers containing vim-dirtytalk, a wordlist for programmers containing
common programming terms. common programming terms.
Setting this value as `true` has the same effect ::: {.note}
as setting {option}`vim.spellCheck.enable` Enabling this option will unconditionally set
{option}`vim.spellcheck.enable` to true as vim-dirtytalk
depends on spellchecking having been set up.
:::
''; '';
*/
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.luaConfigRC.spellcheck = entryAfter ["basic"] '' vim = {
vim.opt.spell = true additionalRuntimePaths = let
vim.opt.spelllang = ${listToLuaTable cfg.languages} compileJoinedSpellfiles =
pkgs.runCommandLocal "nvf-compile-spellfiles" {
# Use the same version of Neovim as the user's configuration
nativeBuildInputs = [config.vim.package];
-- Disable spellchecking for certain filetypes spellfilesJoined = pkgs.symlinkJoin {
-- as configured by `vim.spellcheck.ignoredFiletypes` name = "nvf-spellfiles-joined";
vim.api.nvim_create_autocmd({ "FileType" }, { paths = mapAttrsToList (name: value: pkgs.writeTextDir "spell/${name}.add" (concatLines value)) cfg.extraSpellWords;
pattern = ${listToLuaTable cfg.ignoredFiletypes}, postBuild = "echo Spellfiles joined";
callback = function() };
vim.opt_local.spell = false } ''
end, # Fail on unset variables and non-zero exit codes
}) # this might be the only way to trace when `nvim --headless`
''; # fails in batch mode
set -eu
mkdir -p "$out/spell"
for spellfile in "$spellfilesJoined"/spell/*.add; do
name="$(basename "$spellfile" ".add")"
echo "Compiling spellfile: $spellfile"
nvim --headless --clean \
--cmd "mkspell $out/spell/$name.add.spl $spellfile" -Es -n
done
'';
in
mkIf (cfg.extraSpellWords != {}) [
# If .outPath is missing, additionalRuntimePaths receives the *function*
# instead of a path, causing errors.
compileJoinedSpellfiles.outPath
];
luaConfigRC.spellcheck = entryAfter ["basic"] ''
vim.opt.spell = true
vim.opt.spelllang = ${listToLuaTable cfg.languages}
-- Disable spellchecking for certain filetypes
-- as configured by `vim.spellcheck.ignoredFiletypes`
vim.api.nvim_create_augroup("nvf_autocmds", {clear = false})
vim.api.nvim_create_autocmd({ "FileType" }, {
group = "nvf_autocmds",
pattern = ${listToLuaTable cfg.ignoredFiletypes},
callback = function()
vim.opt_local.spell = false
end,
})
'';
};
}; };
} }

View file

@ -4,11 +4,8 @@
... ...
}: let }: let
inherit (builtins) toJSON; inherit (builtins) toJSON;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.modules) mkIf;
inherit (lib.modules) mkIf mkMerge; inherit (lib.strings) optionalString;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.lists) optionals;
inherit (lib.nvim.binds) mkLuaBinding;
cfg = config.vim.assistant.copilot; cfg = config.vim.assistant.copilot;
@ -23,65 +20,68 @@
end end
end end
''; '';
mkLuaKeymap = mode: key: action: desc: opts:
opts
// {
inherit mode key action desc;
lua = true;
};
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = vim = {
[ lazy.plugins = {
"copilot-lua" copilot-lua = {
# cfg.copilotNodePackage package = "copilot-lua";
] setupModule = "copilot";
++ optionals cfg.cmp.enable [ inherit (cfg) setupOpts;
"copilot-cmp" after = mkIf cfg.cmp.enable "require('copilot_cmp').setup()";
];
vim.autocomplete.nvim-cmp.sources = {copilot = "[Copilot]";}; cmd = ["Copilot" "CopilotAuth" "CopilotDetach" "CopilotPanel" "CopilotStop"];
keys = [
(mkLuaKeymap ["n"] cfg.mappings.panel.accept (wrapPanelBinding ''require("copilot.panel").accept'' cfg.mappings.panel.accept) "[copilot] Accept suggestion" {})
(mkLuaKeymap ["n"] cfg.mappings.panel.jumpNext (wrapPanelBinding "require(\"copilot.panel\").jump_next" cfg.mappings.panel.jumpNext) "[copilot] Accept suggestion" {})
(mkLuaKeymap ["n"] cfg.mappings.panel.jumpPrev (wrapPanelBinding "require(\"copilot.panel\").jump_prev" cfg.mappings.panel.jumpPrev) "[copilot] Accept suggestion" {})
(mkLuaKeymap ["n"] cfg.mappings.panel.refresh (wrapPanelBinding "require(\"copilot.panel\").refresh" cfg.mappings.panel.refresh) "[copilot] Accept suggestion" {})
(mkLuaKeymap ["n"] cfg.mappings.panel.open (wrapPanelBinding ''
function() require("copilot.panel").open({ position = "${cfg.setupOpts.panel.layout.position}", ratio = ${toString cfg.setupOpts.panel.layout.ratio}, }) end
''
cfg.mappings.panel.open) "[copilot] Accept suggestion" {})
vim.pluginRC.copilot = entryAnywhere '' (mkLuaKeymap ["i"] cfg.mappings.suggestion.accept "function() require('copilot.suggestion').accept() end" "[copilot] Accept suggestion" {})
require("copilot").setup(${toLuaObject cfg.setupOpts}) (mkLuaKeymap ["i"] cfg.mappings.suggestion.acceptLine "function() require('copilot.suggestion').accept_line() end" "[copilot] Accept suggestion (line)" {})
(mkLuaKeymap ["i"] cfg.mappings.suggestion.acceptWord "function() require('copilot.suggestion').accept_word() end" "[copilot] Accept suggestion (word)" {})
${lib.optionalString cfg.cmp.enable '' (mkLuaKeymap ["i"] cfg.mappings.suggestion.dismiss "function() require('copilot.suggestion').dismiss() end" "[copilot] dismiss suggestion" {})
require("copilot_cmp").setup() (mkLuaKeymap ["i"] cfg.mappings.suggestion.next "function() require('copilot.suggestion').next() end" "[copilot] next suggestion" {})
''} (mkLuaKeymap ["i"] cfg.mappings.suggestion.prev "function() require('copilot.suggestion').prev() end" "[copilot] previous suggestion" {})
''; ];
};
# Disable plugin handled keymaps.
# Setting it here so that it doesn't show up in user docs
vim.assistant.copilot.setupOpts = {
panel.keymap = {
jump_prev = lib.mkDefault false;
jump_next = lib.mkDefault false;
accept = lib.mkDefault false;
refresh = lib.mkDefault false;
open = lib.mkDefault false;
}; };
suggestion.keymap = {
accept = lib.mkDefault false; autocomplete.nvim-cmp = {
accept_word = lib.mkDefault false; sources = {copilot = "[Copilot]";};
accept_line = lib.mkDefault false; sourcePlugins = ["copilot-cmp"];
next = lib.mkDefault false; };
prev = lib.mkDefault false;
dismiss = lib.mkDefault false; # Disable plugin handled keymaps.
# Setting it here so that it doesn't show up in user docs
assistant.copilot.setupOpts = {
panel.keymap = {
jump_prev = lib.mkDefault false;
jump_next = lib.mkDefault false;
accept = lib.mkDefault false;
refresh = lib.mkDefault false;
open = lib.mkDefault false;
};
suggestion.keymap = {
accept = lib.mkDefault false;
accept_word = lib.mkDefault false;
accept_line = lib.mkDefault false;
next = lib.mkDefault false;
prev = lib.mkDefault false;
dismiss = lib.mkDefault false;
};
}; };
}; };
vim.maps.normal = mkMerge [
(mkLuaBinding cfg.mappings.panel.jumpPrev (wrapPanelBinding "require(\"copilot.panel\").jump_prev" cfg.mappings.panel.jumpPrev) "[copilot] Accept suggestion")
(mkLuaBinding cfg.mappings.panel.jumpNext (wrapPanelBinding "require(\"copilot.panel\").jump_next" cfg.mappings.panel.jumpNext) "[copilot] Accept suggestion")
(mkLuaBinding cfg.mappings.panel.accept (wrapPanelBinding ''require("copilot.panel").accept'' cfg.mappings.panel.accept) "[copilot] Accept suggestion")
(mkLuaBinding cfg.mappings.panel.refresh (wrapPanelBinding "require(\"copilot.panel\").refresh" cfg.mappings.panel.refresh) "[copilot] Accept suggestion")
(mkLuaBinding cfg.mappings.panel.open (wrapPanelBinding ''
function() require("copilot.panel").open({ position = "${cfg.setupOpts.panel.layout.position}", ratio = ${toString cfg.setupOpts.panel.layout.ratio}, }) end
''
cfg.mappings.panel.open) "[copilot] Accept suggestion")
];
vim.maps.insert = mkMerge [
(mkLuaBinding cfg.mappings.suggestion.accept "require(\"copilot.suggestion\").accept" "[copilot] Accept suggestion")
(mkLuaBinding cfg.mappings.suggestion.acceptLine "require(\"copilot.suggestion\").accept_line" "[copilot] Accept suggestion (line)")
(mkLuaBinding cfg.mappings.suggestion.acceptWord "require(\"copilot.suggestion\").accept_word" "[copilot] Accept suggestion (word)")
(mkLuaBinding cfg.mappings.suggestion.next "require(\"copilot.suggestion\").next" "[copilot] next suggestion")
(mkLuaBinding cfg.mappings.suggestion.prev "require(\"copilot.suggestion\").prev" "[copilot] previous suggestion")
(mkLuaBinding cfg.mappings.suggestion.dismiss "require(\"copilot.suggestion\").dismiss" "[copilot] dismiss suggestion")
];
}; };
} }

View file

@ -1,6 +1,7 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkEnableOption; inherit (lib.options) mkEnableOption;
inherit (lib.nvim.binds) mkMappingOption; inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
options.vim.comments.comment-nvim = { options.vim.comments.comment-nvim = {
enable = mkEnableOption "smart and powerful comment plugin for neovim comment-nvim"; enable = mkEnableOption "smart and powerful comment plugin for neovim comment-nvim";
@ -15,5 +16,12 @@ in {
toggleSelectedLine = mkMappingOption "Toggle selected comment" "gc"; toggleSelectedLine = mkMappingOption "Toggle selected comment" "gc";
toggleSelectedBlock = mkMappingOption "Toggle selected block" "gb"; toggleSelectedBlock = mkMappingOption "Toggle selected block" "gb";
}; };
setupOpts = mkPluginSetupOption "Comment-nvim" {
mappings = {
basic = mkEnableOption "basic mappings";
extra = mkEnableOption "extra mappings";
};
};
}; };
} }

View file

@ -3,46 +3,38 @@
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf;
inherit (lib.nvim.binds) mkExprBinding mkBinding; inherit (lib.nvim.binds) mkLznExprBinding mkLznBinding;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.comments.comment-nvim; cfg = config.vim.comments.comment-nvim;
self = import ./comment-nvim.nix {inherit lib;}; self = import ./comment-nvim.nix {inherit lib;};
inherit (self.options.vim.comments.comment-nvim) mappings; inherit (self.options.vim.comments.comment-nvim) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = ["comment-nvim"]; vim.lazy.plugins.comment-nvim = {
package = "comment-nvim";
vim.maps.normal = mkMerge [ setupModule = "Comment";
(mkBinding cfg.mappings.toggleOpLeaderLine "<Plug>(comment_toggle_linewise)" mappings.toggleOpLeaderLine.description) inherit (cfg) setupOpts;
(mkBinding cfg.mappings.toggleOpLeaderBlock "<Plug>(comment_toggle_blockwise)" mappings.toggleOpLeaderBlock.description) keys = [
(mkLznBinding ["n"] cfg.mappings.toggleOpLeaderLine "<Plug>(comment_toggle_linewise)" mappings.toggleOpLeaderLine.description)
(mkExprBinding cfg.mappings.toggleCurrentLine '' (mkLznBinding ["n"] cfg.mappings.toggleOpLeaderBlock "<Plug>(comment_toggle_blockwise)" mappings.toggleOpLeaderBlock.description)
function() (mkLznExprBinding ["n"] cfg.mappings.toggleCurrentLine ''
return vim.api.nvim_get_vvar('count') == 0 and '<Plug>(comment_toggle_linewise_current)' function()
or '<Plug>(comment_toggle_linewise_count)' return vim.api.nvim_get_vvar('count') == 0 and '<Plug>(comment_toggle_linewise_current)'
end or '<Plug>(comment_toggle_linewise_count)'
'' end
mappings.toggleCurrentLine.description) ''
(mkExprBinding cfg.mappings.toggleCurrentBlock '' mappings.toggleCurrentLine.description)
function() (mkLznExprBinding ["n"] cfg.mappings.toggleCurrentBlock ''
return vim.api.nvim_get_vvar('count') == 0 and '<Plug>(comment_toggle_blockwise_current)' function()
or '<Plug>(comment_toggle_blockwise_count)' return vim.api.nvim_get_vvar('count') == 0 and '<Plug>(comment_toggle_blockwise_current)'
end or '<Plug>(comment_toggle_blockwise_count)'
'' end
mappings.toggleCurrentBlock.description) ''
]; mappings.toggleCurrentBlock.description)
(mkLznBinding ["x"] cfg.mappings.toggleSelectedLine "<Plug>(comment_toggle_linewise_visual)" mappings.toggleSelectedLine.description)
vim.maps.visual = mkMerge [ (mkLznBinding ["x"] cfg.mappings.toggleSelectedBlock "<Plug>(comment_toggle_blockwise_visual)" mappings.toggleSelectedBlock.description)
(mkBinding cfg.mappings.toggleSelectedLine "<Plug>(comment_toggle_linewise_visual)" mappings.toggleSelectedLine.description) ];
(mkBinding cfg.mappings.toggleSelectedBlock "<Plug>(comment_toggle_blockwise_visual)" mappings.toggleSelectedBlock.description) };
];
vim.pluginRC.comment-nvim = entryAnywhere ''
require('Comment').setup({
mappings = { basic = false, extra = false, },
})
'';
}; };
} }

View file

@ -3,91 +3,122 @@
config, config,
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf mkMerge;
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (builtins) attrNames; inherit (lib.nvim.attrsets) mapListToAttrs;
inherit (builtins) attrNames typeOf tryEval concatStringsSep;
cfg = config.vim.autocomplete.nvim-cmp; cfg = config.vim.autocomplete.nvim-cmp;
luasnipEnable = config.vim.snippets.luasnip.enable; luasnipEnable = config.vim.snippets.luasnip.enable;
getPluginName = plugin:
if typeOf plugin == "string"
then plugin
else if (plugin ? pname && (tryEval plugin.pname).success)
then plugin.pname
else plugin.name;
inherit (cfg) mappings; inherit (cfg) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = [ startPlugins = ["rtp-nvim"];
"nvim-cmp" lazy.plugins = mkMerge [
"cmp-buffer" (mapListToAttrs (package: {
"cmp-path" name = getPluginName package;
value = {
inherit package;
lazy = true;
after = ''
local path = vim.fn.globpath(vim.o.packpath, 'pack/*/opt/${getPluginName package}')
require("rtp_nvim").source_after_plugin_dir(path)
'';
};
})
cfg.sourcePlugins)
{
nvim-cmp = {
package = "nvim-cmp";
after = ''
${optionalString luasnipEnable "local luasnip = require('luasnip')"}
local cmp = require("cmp")
cmp.setup(${toLuaObject cfg.setupOpts})
${optionalString config.vim.lazy.enable
(concatStringsSep "\n" (map
(package: "require('lz.n').trigger_load(${toLuaObject (getPluginName package)})")
cfg.sourcePlugins))}
'';
event = ["InsertEnter" "CmdlineEnter"];
};
}
]; ];
autocomplete.nvim-cmp.sources = { autocomplete.nvim-cmp = {
nvim-cmp = null; sources = {
buffer = "[Buffer]"; nvim-cmp = null;
path = "[Path]"; buffer = "[Buffer]";
}; path = "[Path]";
autocomplete.nvim-cmp.setupOpts = {
sources = map (s: {name = s;}) (attrNames cfg.sources);
# 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()";
}; };
formatting.format = cfg.format; sourcePlugins = ["cmp-buffer" "cmp-path"];
};
pluginRC.nvim-cmp = mkIf cfg.enable (entryAfter ["autopairs" "luasnip"] '' setupOpts = {
${optionalString luasnipEnable "local luasnip = require('luasnip')"} sources = map (s: {name = s;}) (attrNames cfg.sources);
local cmp = require("cmp")
cmp.setup(${toLuaObject cfg.setupOpts})
'');
# `cmp` and `luasnip` are defined above, in the `nvim-cmp` section # TODO: try to get nvim-cmp to follow global border style
autocomplete.nvim-cmp.setupOpts.mapping = { window = mkIf config.vim.ui.borders.enable {
${mappings.complete} = mkLuaInline "cmp.mapping.complete()"; completion = mkLuaInline "cmp.config.window.bordered()";
${mappings.close} = mkLuaInline "cmp.mapping.abort()"; documentation = mkLuaInline "cmp.config.window.bordered()";
${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 '' formatting.format = cfg.format;
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` and `luasnip` are defined above, in the `nvim-cmp` section
cmp.select_next_item() mapping = {
${optionalString luasnipEnable '' ${mappings.complete} = mkLuaInline "cmp.mapping.complete()";
elseif luasnip.locally_jumpable(1) then ${mappings.close} = mkLuaInline "cmp.mapping.abort()";
luasnip.jump(1) ${mappings.scrollDocsUp} = mkLuaInline "cmp.mapping.scroll_docs(-4)";
''} ${mappings.scrollDocsDown} = mkLuaInline "cmp.mapping.scroll_docs(4)";
elseif has_words_before() then ${mappings.confirm} = mkLuaInline "cmp.mapping.confirm({ select = true })";
cmp.complete()
else
fallback()
end
end)
'';
${mappings.previous} = mkLuaInline '' ${mappings.next} = mkLuaInline ''
cmp.mapping(function(fallback) cmp.mapping(function(fallback)
if cmp.visible() then local has_words_before = function()
cmp.select_prev_item() local line, col = unpack(vim.api.nvim_win_get_cursor(0))
${optionalString luasnipEnable '' return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
elseif luasnip.locally_jumpable(-1) then end
luasnip.jump(-1)
''} if cmp.visible() then
else cmp.select_next_item()
fallback() ${optionalString luasnipEnable ''
end elseif luasnip.locally_jumpable(1) then
end) 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

@ -4,10 +4,10 @@
... ...
}: let }: let
inherit (lib.options) mkEnableOption mkOption literalExpression literalMD; inherit (lib.options) mkEnableOption mkOption literalExpression literalMD;
inherit (lib.types) str attrsOf nullOr either; inherit (lib.types) str attrsOf nullOr either listOf;
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.binds) mkMappingOption; inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.nvim.types) mkPluginSetupOption luaInline mergelessListOf; inherit (lib.nvim.types) mkPluginSetupOption luaInline mergelessListOf pluginType;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (builtins) isString; inherit (builtins) isString;
@ -99,5 +99,11 @@ in {
} }
''; '';
}; };
sourcePlugins = mkOption {
type = listOf pluginType;
default = [];
description = "List of source plugins used by nvim-cmp.";
};
}; };
} }

View file

@ -6,7 +6,7 @@
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) mapAttrs; inherit (lib.attrsets) mapAttrs;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetLuaBinding; inherit (lib.nvim.binds) addDescriptionsToMappings mkSetLuaBinding mkSetLuaLznBinding;
inherit (lib.nvim.dag) entryAnywhere entryAfter; inherit (lib.nvim.dag) entryAnywhere entryAfter;
cfg = config.vim.debugger.nvim-dap; cfg = config.vim.debugger.nvim-dap;
@ -52,24 +52,31 @@ in {
}) })
(mkIf (cfg.enable && cfg.ui.enable) { (mkIf (cfg.enable && cfg.ui.enable) {
vim = { vim = {
startPlugins = ["nvim-dap-ui" "nvim-nio"]; startPlugins = ["nvim-nio"];
pluginRC.nvim-dap-ui = entryAfter ["nvim-dap"] ('' lazy.plugins.nvim-dap-ui = {
local dapui = require("dapui") package = "nvim-dap-ui";
dapui.setup() setupModule = "dapui";
'' inherit (cfg.ui) setupOpts;
+ optionalString cfg.ui.autoStart ''
keys = [
(mkSetLuaLznBinding mappings.toggleDapUI "function() require('dapui').toggle() end")
];
};
pluginRC.nvim-dap-ui = entryAfter ["nvim-dap"] (
optionalString cfg.ui.autoStart ''
dap.listeners.after.event_initialized["dapui_config"] = function() dap.listeners.after.event_initialized["dapui_config"] = function()
dapui.open() require("dapui").open()
end end
dap.listeners.before.event_terminated["dapui_config"] = function() dap.listeners.before.event_terminated["dapui_config"] = function()
dapui.close() require("dapui").close()
end end
dap.listeners.before.event_exited["dapui_config"] = function() dap.listeners.before.event_exited["dapui_config"] = function()
dapui.close() require("dapui").close()
end end
''); ''
maps.normal = mkSetLuaBinding mappings.toggleDapUI "require('dapui').toggle"; );
}; };
}) })
]; ];

View file

@ -2,12 +2,16 @@
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.types) bool attrsOf str; inherit (lib.types) bool attrsOf str;
inherit (lib.nvim.binds) mkMappingOption; inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
options.vim.debugger.nvim-dap = { options.vim.debugger.nvim-dap = {
enable = mkEnableOption "debugging via nvim-dap"; enable = mkEnableOption "debugging via nvim-dap";
ui = { ui = {
enable = mkEnableOption "UI extension for nvim-dap"; enable = mkEnableOption "UI extension for nvim-dap";
setupOpts = mkPluginSetupOption "nvim-dap-ui" {};
autoStart = mkOption { autoStart = mkOption {
type = bool; type = bool;
default = true; default = true;

View file

@ -4,8 +4,6 @@
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.filetree.neo-tree; cfg = config.vim.filetree.neo-tree;
in { in {
@ -16,15 +14,17 @@ in {
"plenary-nvim" # commons library "plenary-nvim" # commons library
"image-nvim" # optional for image previews "image-nvim" # optional for image previews
"nui-nvim" # ui library "nui-nvim" # ui library
# neotree
"neo-tree-nvim"
]; ];
visuals.nvimWebDevicons.enable = true; lazy.plugins.neo-tree-nvim = {
package = "neo-tree-nvim";
setupModule = "neo-tree";
inherit (cfg) setupOpts;
pluginRC.neo-tree = entryAnywhere '' cmd = ["Neotree"];
require("neo-tree").setup(${toLuaObject cfg.setupOpts}) };
'';
visuals.nvimWebDevicons.enable = true;
}; };
}; };
} }

View file

@ -5,10 +5,9 @@
... ...
}: let }: let
inherit (lib.strings) optionalString; inherit (lib.strings) optionalString;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf;
inherit (lib.nvim.binds) mkBinding; inherit (lib.nvim.binds) mkLznBinding;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.binds) pushDownDefault; inherit (lib.nvim.binds) pushDownDefault;
cfg = config.vim.filetree.nvimTree; cfg = config.vim.filetree.nvimTree;
@ -16,69 +15,74 @@
inherit (self.options.vim.filetree.nvimTree) mappings; inherit (self.options.vim.filetree.nvimTree) mappings;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = ["nvim-tree-lua"]; vim = {
binds.whichKey.register = pushDownDefault {
"<leader>t" = "+NvimTree";
};
vim.maps.normal = mkMerge [ lazy.plugins.nvim-tree-lua = {
(mkBinding cfg.mappings.toggle ":NvimTreeToggle<cr>" mappings.toggle.description) package = "nvim-tree-lua";
(mkBinding cfg.mappings.refresh ":NvimTreeRefresh<cr>" mappings.refresh.description) setupModule = "nvim-tree";
(mkBinding cfg.mappings.findFile ":NvimTreeFindFile<cr>" mappings.findFile.description) inherit (cfg) setupOpts;
(mkBinding cfg.mappings.focus ":NvimTreeFocus<cr>" mappings.focus.description) cmd = ["NvimTreeClipboard" "NvimTreeClose" "NvimTreeCollapse" "NvimTreeCollapseKeepBuffers" "NvimTreeFindFile" "NvimTreeFindFileToggle" "NvimTreeFocus" "NvimTreeHiTest" "NvimTreeOpen" "NvimTreeRefresh" "NvimTreeResize" "NvimTreeToggle"];
]; keys = [
(mkLznBinding ["n"] cfg.mappings.toggle ":NvimTreeToggle<cr>" mappings.toggle.description)
(mkLznBinding ["n"] cfg.mappings.refresh ":NvimTreeRefresh<cr>" mappings.refresh.description)
(mkLznBinding ["n"] cfg.mappings.findFile ":NvimTreeFindFile<cr>" mappings.findFile.description)
(mkLznBinding ["n"] cfg.mappings.focus ":NvimTreeFocus<cr>" mappings.focus.description)
];
};
vim.binds.whichKey.register = pushDownDefault { pluginRC.nvimtreelua = entryAnywhere ''
"<leader>t" = "+NvimTree"; ${
optionalString cfg.setupOpts.disable_netrw ''
-- disable netrew completely
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
''
}
${
optionalString cfg.openOnSetup ''
${optionalString config.vim.lazy.enable ''require('lz.n').trigger_load("nvim-tree-lua")''}
-- autostart behaviour
-- Open on startup has been deprecated
-- see https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup
-- use a nix eval to dynamically insert the open on startup function
local function open_nvim_tree(data)
local IGNORED_FT = {
"markdown",
}
-- buffer is a real file on the disk
local real_file = vim.fn.filereadable(data.file) == 1
-- buffer is a [No Name]
local no_name = data.file == "" and vim.bo[data.buf].buftype == ""
-- &ft
local filetype = vim.bo[data.buf].ft
-- only files please
if not real_file and not no_name then
return
end
-- skip ignored filetypes
if vim.tbl_contains(IGNORED_FT, filetype) then
return
end
-- open the tree but don't focus it
require("nvim-tree.api").tree.toggle({ focus = false })
end
-- function to automatically open the tree on VimEnter
vim.api.nvim_create_autocmd({ "VimEnter" }, { callback = open_nvim_tree })
''
}
'';
}; };
vim.pluginRC.nvimtreelua = entryAnywhere ''
${
optionalString cfg.setupOpts.disable_netrw ''
-- disable netrew completely
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
''
}
require'nvim-tree'.setup(${toLuaObject cfg.setupOpts})
${
optionalString cfg.openOnSetup ''
-- autostart behaviour
-- Open on startup has been deprecated
-- see https://github.com/nvim-tree/nvim-tree.lua/wiki/Open-At-Startup
-- use a nix eval to dynamically insert the open on startup function
local function open_nvim_tree(data)
local IGNORED_FT = {
"markdown",
}
-- buffer is a real file on the disk
local real_file = vim.fn.filereadable(data.file) == 1
-- buffer is a [No Name]
local no_name = data.file == "" and vim.bo[data.buf].buftype == ""
-- &ft
local filetype = vim.bo[data.buf].ft
-- only files please
if not real_file and not no_name then
return
end
-- skip ignored filetypes
if vim.tbl_contains(IGNORED_FT, filetype) then
return
end
-- open the tree but don't focus it
require("nvim-tree.api").tree.toggle({ focus = false })
end
-- function to automatically open the tree on VimEnter
vim.api.nvim_create_autocmd({ "VimEnter" }, { callback = open_nvim_tree })
''
}
'';
}; };
} }

View file

@ -5,7 +5,6 @@
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.lists) optional;
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;
@ -23,9 +22,10 @@
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = optional usingNvimCmp "cmp-nvim-lsp"; autocomplete.nvim-cmp = {
sources = {nvim_lsp = "[LSP]";};
autocomplete.nvim-cmp.sources = {nvim_lsp = "[LSP]";}; sourcePlugins = ["cmp-nvim-lsp"];
};
pluginRC.lsp-setup = '' pluginRC.lsp-setup = ''
vim.g.formatsave = ${boolToString cfg.formatOnSave}; vim.g.formatsave = ${boolToString cfg.formatOnSave};
@ -116,7 +116,60 @@ in {
end end
local capabilities = vim.lsp.protocol.make_client_capabilities() local capabilities = vim.lsp.protocol.make_client_capabilities()
${optionalString usingNvimCmp "capabilities = require('cmp_nvim_lsp').default_capabilities()"} ${optionalString usingNvimCmp ''
-- HACK: copied from cmp-nvim-lsp. If we ever lazy load lspconfig we
-- should re-evaluate whether we can just use `default_capabilities`
capabilities = {
textDocument = {
completion = {
dynamicRegistration = false,
completionItem = {
snippetSupport = true,
commitCharactersSupport = true,
deprecatedSupport = true,
preselectSupport = true,
tagSupport = {
valueSet = {
1, -- Deprecated
}
},
insertReplaceSupport = true,
resolveSupport = {
properties = {
"documentation",
"detail",
"additionalTextEdits",
"sortText",
"filterText",
"insertText",
"textEdit",
"insertTextFormat",
"insertTextMode",
},
},
insertTextModeSupport = {
valueSet = {
1, -- asIs
2, -- adjustIndentation
}
},
labelDetailsSupport = true,
},
contextSupport = true,
insertTextMode = 1,
completionList = {
itemDefaults = {
'commitCharacters',
'editRange',
'insertTextFormat',
'insertTextMode',
'data',
}
}
},
},
}
''}
''; '';
}; };
}; };

View file

@ -1,41 +1,40 @@
{ {
config, config,
lib, lib,
options,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.nvim.binds) addDescriptionsToMappings mkSetLznBinding pushDownDefault;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetBinding pushDownDefault;
cfg = config.vim.lsp; cfg = config.vim.lsp;
self = import ./trouble.nix {inherit lib;}; mappingDefinitions = options.vim.lsp.trouble.mappings;
mappingDefinitions = self.options.vim.lsp.trouble.mappings;
mappings = addDescriptionsToMappings cfg.trouble.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.trouble.mappings mappingDefinitions;
in { in {
config = mkIf (cfg.enable && cfg.trouble.enable) { config = mkIf (cfg.enable && cfg.trouble.enable) {
vim = { vim = {
startPlugins = ["trouble"]; lazy.plugins.trouble = {
package = "trouble";
setupModule = "trouble";
inherit (cfg.trouble) setupOpts;
maps.normal = mkMerge [ cmd = "Trouble";
(mkSetBinding mappings.toggle "<cmd>TroubleToggle<CR>") keys = [
(mkSetBinding mappings.workspaceDiagnostics "<cmd>TroubleToggle workspace_diagnostics<CR>") (mkSetLznBinding mappings.toggle "<cmd>TroubleToggle<CR>")
(mkSetBinding mappings.documentDiagnostics "<cmd>TroubleToggle document_diagnostics<CR>") (mkSetLznBinding mappings.workspaceDiagnostics "<cmd>TroubleToggle workspace_diagnostics<CR>")
(mkSetBinding mappings.lspReferences "<cmd>TroubleToggle lsp_references<CR>") (mkSetLznBinding mappings.documentDiagnostics "<cmd>TroubleToggle document_diagnostics<CR>")
(mkSetBinding mappings.quickfix "<cmd>TroubleToggle quickfix<CR>") (mkSetLznBinding mappings.lspReferences "<cmd>TroubleToggle lsp_references<CR>")
(mkSetBinding mappings.locList "<cmd>TroubleToggle loclist<CR>") (mkSetLznBinding mappings.quickfix "<cmd>TroubleToggle quickfix<CR>")
]; (mkSetLznBinding mappings.locList "<cmd>TroubleToggle loclist<CR>")
];
};
binds.whichKey.register = pushDownDefault { binds.whichKey.register = pushDownDefault {
"<leader>l" = "Trouble"; "<leader>l" = "Trouble";
"<leader>x" = "+Trouble"; "<leader>x" = "+Trouble";
"<leader>lw" = "Workspace"; "<leader>lw" = "Workspace";
}; };
pluginRC.trouble = entryAnywhere ''
-- Enable trouble diagnostics viewer
require("trouble").setup {}
'';
}; };
}; };
} }

View file

@ -1,11 +1,14 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkEnableOption; inherit (lib.options) mkEnableOption;
inherit (lib.nvim.binds) mkMappingOption; inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
options.vim.lsp = { options.vim.lsp = {
trouble = { trouble = {
enable = mkEnableOption "trouble diagnostics viewer"; enable = mkEnableOption "trouble diagnostics viewer";
setupOpts = mkPluginSetupOption "Trouble" {};
mappings = { mappings = {
toggle = mkMappingOption "Toggle trouble [trouble]" "<leader>xx"; toggle = mkMappingOption "Toggle trouble [trouble]" "<leader>xx";
workspaceDiagnostics = mkMappingOption "Workspace diagnostics [trouble]" "<leader>lwd"; workspaceDiagnostics = mkMappingOption "Workspace diagnostics [trouble]" "<leader>lwd";

View file

@ -9,9 +9,18 @@
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = ["luasnip" "cmp-luasnip"] ++ cfg.providers; lazy.plugins = {
autocomplete.nvim-cmp.sources = {luasnip = "[LuaSnip]";}; luasnip = {
pluginRC.luasnip = cfg.loaders; package = "luasnip";
lazy = true;
after = cfg.loaders;
};
};
startPlugins = cfg.providers;
autocomplete.nvim-cmp = {
sources = {luasnip = "[LuaSnip]";};
sourcePlugins = ["cmp-luasnip"];
};
}; };
}; };
} }

View file

@ -7,16 +7,26 @@
inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.dag) entryAfter;
cfg = config.vim.spellcheck; cfg = config.vim.spellcheck;
in { in {
config = mkIf (cfg.enable && cfg.programmingWordlist.enable) { config = mkIf cfg.programmingWordlist.enable {
vim = { vim = {
startPlugins = ["vim-dirtytalk"]; startPlugins = ["vim-dirtytalk"];
# vim-dirtytalk doesn't have any setup spellcheck.enable = true;
# but we would like to append programming to spelllang
# as soon as possible while the plugin is enabled # vim-dirtytalk doesn't have any setup but we would
pluginRC.vim-dirtytalk = entryAfter ["basic"] '' # like to append programming to spelllangs as soon as
-- append programming to spelllang # possible while the plugin is enabled and the state
vim.opt.spelllang:append("programming") # directory can be found.
pluginRC.vim-dirtytalk = entryAfter ["spellcheck"] ''
-- If Neovim can find (or access) the state directory
-- then append "programming" wordlist from vim-dirtytalk
-- to spelllang table. If path cannot be found, display
-- an error and avoid appending the programming words
if vim.fn.isdirectory(vim.fn.stdpath('state')) == 1 then
vim.opt.spelllang:append("programming")
else
vim.notify("State path does not exist: " .. state_path, vim.log.levels.ERROR)
end
''; '';
}; };
}; };

View file

@ -15,10 +15,14 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = [ startPlugins = [
(assert config.vim.visuals.nvimWebDevicons.enable; "nvim-bufferline-lua") "nvim-bufferline-lua"
"bufdelete-nvim" "bufdelete-nvim"
]; ];
# Soft-dependency for bufferline.
# Recommended by upstream, so enabled here.
visuals.nvim-web-devicons.enable = true;
maps.normal = mkMerge [ maps.normal = mkMerge [
(mkLuaBinding cfg.mappings.closeCurrent "require(\"bufdelete\").bufdelete" mappings.closeCurrent.description) (mkLuaBinding cfg.mappings.closeCurrent "require(\"bufdelete\").bufdelete" mappings.closeCurrent.description)
(mkBinding cfg.mappings.cycleNext ":BufferLineCycleNext<CR>" mappings.cycleNext.description) (mkBinding cfg.mappings.cycleNext ":BufferLineCycleNext<CR>" mappings.cycleNext.description)

View file

@ -3,39 +3,31 @@
lib, lib,
... ...
}: let }: let
inherit (builtins) toJSON; inherit (lib.strings) optionalString;
inherit (lib.lists) optionals; inherit (lib.lists) optional;
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf;
inherit (lib.meta) getExe; inherit (lib.meta) getExe;
inherit (lib.nvim.binds) mkBinding; inherit (lib.nvim.binds) mkLznBinding;
inherit (lib.nvim.dag) entryAnywhere entryAfter;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.terminal.toggleterm; cfg = config.vim.terminal.toggleterm;
lazygitMapDesc = "Open lazygit [toggleterm]";
in { in {
config = mkMerge [ config = mkIf cfg.enable {
( vim = {
mkIf cfg.enable { lazy.plugins.toggleterm-nvim = {
vim = { package = "toggleterm-nvim";
startPlugins = [ cmd = ["ToggleTerm" "ToggleTermSendCurrentLine" "ToggleTermSendVisualLines" "ToggleTermSendVisualSelection" "ToggleTermSetName" "ToggleTermToggleAll"];
"toggleterm-nvim" keys =
]; [(mkLznBinding ["n"] cfg.mappings.open "<Cmd>execute v:count . \"ToggleTerm\"<CR>" "Toggle terminal")]
++ optional cfg.lazygit.enable {
key = cfg.lazygit.mappings.open;
desc = lazygitMapDesc;
};
maps.normal = mkBinding cfg.mappings.open "<Cmd>execute v:count . \"ToggleTerm\"<CR>" "Toggle terminal"; setupModule = "toggleterm";
inherit (cfg) setupOpts;
pluginRC.toggleterm = entryAnywhere '' after = optionalString cfg.lazygit.enable ''
require("toggleterm").setup(${toLuaObject cfg.setupOpts})
'';
};
}
)
(
mkIf (cfg.enable && cfg.lazygit.enable)
{
vim.startPlugins = optionals (cfg.lazygit.package != null) [
cfg.lazygit.package
];
vim.pluginRC.toggleterm-lazygit = entryAfter ["toggleterm"] ''
local terminal = require 'toggleterm.terminal' local terminal = require 'toggleterm.terminal'
local lazygit = terminal.Terminal:new({ local lazygit = terminal.Terminal:new({
cmd = '${ cmd = '${
@ -50,9 +42,9 @@ in {
end end
}) })
vim.keymap.set('n', ${toJSON cfg.lazygit.mappings.open}, function() lazygit:toggle() end, {silent = true, noremap = true, desc = 'Open lazygit [toggleterm]'}) vim.keymap.set('n', ${toLuaObject cfg.lazygit.mappings.open}, function() lazygit:toggle() end, {silent = true, noremap = true, desc = '${lazygitMapDesc}'})
''; '';
} };
) };
]; };
} }

View file

@ -66,7 +66,7 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = [cfg.name]; startPlugins = [cfg.name];
luaConfigRC.theme = entryBefore ["pluginConfigs"] '' luaConfigRC.theme = entryBefore ["pluginConfigs" "lazyConfigs"] ''
${cfg.extraConfig} ${cfg.extraConfig}
${supportedThemes.${cfg.name}.setup {inherit (cfg) style transparent base16-colors;}} ${supportedThemes.${cfg.name}.setup {inherit (cfg) style transparent base16-colors;}}
''; '';

View file

@ -5,13 +5,12 @@
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf mkMerge;
inherit (lib.lists) optional optionals; inherit (lib.lists) optionals;
inherit (lib.nvim.binds) mkSetBinding addDescriptionsToMappings; inherit (lib.nvim.binds) mkSetBinding addDescriptionsToMappings;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryBefore entryAfter; inherit (lib.nvim.dag) entryBefore entryAfter;
cfg = config.vim.treesitter; cfg = config.vim.treesitter;
usingNvimCmp = config.vim.autocomplete.nvim-cmp.enable;
self = import ./treesitter.nix {inherit pkgs lib;}; self = import ./treesitter.nix {inherit pkgs lib;};
mappingDefinitions = self.options.vim.treesitter.mappings; mappingDefinitions = self.options.vim.treesitter.mappings;
@ -19,9 +18,13 @@
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = ["nvim-treesitter"] ++ optional usingNvimCmp "cmp-treesitter"; startPlugins = ["nvim-treesitter"];
autocomplete.nvim-cmp = {
sources = {treesitter = "[Treesitter]";};
sourcePlugins = ["cmp-treesitter"];
};
autocomplete.nvim-cmp.sources = {treesitter = "[Treesitter]";};
treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars; treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars;
maps = { maps = {

View file

@ -4,15 +4,18 @@
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.strings) optionalString;
cfg = config.vim.binds.cheatsheet; cfg = config.vim.binds.cheatsheet;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = ["cheatsheet-nvim"]; vim.lazy.plugins.cheatsheet-nvim = {
package = "cheatsheet-nvim";
setupModule = "cheatsheet";
setupOpts = {};
cmd = ["Cheatsheet" "CheatsheetEdit"];
vim.pluginRC.cheaetsheet-nvim = entryAnywhere '' before = optionalString config.vim.lazy.enable "require('lz.n').trigger_load('telescope')";
require('cheatsheet').setup({}) };
'';
}; };
} }

View file

@ -8,9 +8,14 @@
cfg = config.vim.utility.diffview-nvim; cfg = config.vim.utility.diffview-nvim;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = [ vim = {
"diffview-nvim" startPlugins = ["plenary-nvim"];
"plenary-nvim" lazy.plugins.diffview-nvim = {
]; package = "diffview-nvim";
cmd = ["DiffviewClose" "DiffviewFileHistory" "DiffviewFocusFiles" "DiffviewLog" "DiffviewOpen" "DiffviewRefresh" "DiffviewToggleFiles"];
setupModule = "diffview";
inherit (cfg) setupOpts;
};
};
}; };
} }

View file

@ -1,7 +1,9 @@
{lib, ...}: let {lib, ...}: let
inherit (lib.options) mkEnableOption; inherit (lib.options) mkEnableOption;
inherit (lib.nvim.types) mkPluginSetupOption;
in { in {
options.vim.utility.diffview-nvim = { options.vim.utility.diffview-nvim = {
enable = mkEnableOption "diffview-nvim: cycle through diffs for all modified files for any git rev"; enable = mkEnableOption "diffview-nvim: cycle through diffs for all modified files for any git rev";
setupOpts = mkPluginSetupOption "Fidget" {};
}; };
} }

View file

@ -4,20 +4,20 @@
... ...
}: let }: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkIf;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.utility.icon-picker; cfg = config.vim.utility.icon-picker;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = [ vim.startPlugins = ["dressing-nvim"];
"icon-picker-nvim"
"dressing-nvim"
];
vim.pluginRC.icon-picker = entryAnywhere '' vim.lazy.plugins.icon-picker-nvim = {
require("icon-picker").setup({ package = "icon-picker-nvim";
disable_legacy_commands = true setupModule = "icon-picker";
}) setupOpts = {
''; disable_legacy_commands = true;
};
cmd = ["IconPickerInsert" "IconPickerNormal" "IconPickerYank"];
};
}; };
} }

View file

@ -2,5 +2,6 @@ _: {
imports = [ imports = [
./hop ./hop
./leap ./leap
./precognition
]; ];
} }

View file

@ -3,73 +3,59 @@
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge mkDefault; inherit (lib.modules) mkIf mkDefault;
inherit (lib.nvim.binds) mkBinding; inherit (lib.nvim.binds) mkLznBinding;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.utility.motion.leap; cfg = config.vim.utility.motion.leap;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim.startPlugins = [ vim = {
"leap-nvim" startPlugins = ["vim-repeat"];
"vim-repeat" lazy.plugins.leap-nvim = {
]; package = "leap-nvim";
keys = [
(mkLznBinding ["n" "o" "x"] cfg.mappings.leapForwardTo "<Plug>(leap-forward-to)" "Leap forward to")
(mkLznBinding ["n" "o" "x"] cfg.mappings.leapBackwardTo "<Plug>(leap-backward-to)" "Leap backward to")
(mkLznBinding ["n" "o" "x"] cfg.mappings.leapForwardTill "<Plug>(leap-forward-till)" "Leap forward till")
(mkLznBinding ["n" "o" "x"] cfg.mappings.leapBackwardTill "<Plug>(leap-backward-till)" "Leap backward till")
(mkLznBinding ["n" "o" "x"] cfg.mappings.leapFromWindow "<Plug>(leap-from-window)" "Leap from window")
];
vim.maps.normal = mkMerge [ after = ''
(mkBinding cfg.mappings.leapForwardTo "<Plug>(leap-forward-to)" "Leap forward to") require('leap').opts = {
(mkBinding cfg.mappings.leapBackwardTo "<Plug>(leap-backward-to)" "Leap backward to") max_phase_one_targets = nil,
(mkBinding cfg.mappings.leapFromWindow "<Plug>(leap-from-window)" "Leap from window") highlight_unlabeled_phase_one_targets = false,
]; max_highlighted_traversal_targets = 10,
case_sensitive = false,
equivalence_classes = { ' \t\r\n', },
substitute_chars = {},
safe_labels = {
"s", "f", "n", "u", "t", "/",
"S", "F", "N", "L", "H", "M", "U", "G", "T", "?", "Z"
},
labels = {
"s", "f", "n",
"j", "k", "l", "h", "o", "d", "w", "e", "m", "b",
"u", "y", "v", "r", "g", "t", "c", "x", "/", "z",
"S", "F", "N",
"J", "K", "L", "H", "O", "D", "W", "E", "M", "B",
"U", "Y", "V", "R", "G", "T", "C", "X", "?", "Z"
},
special_keys = {
repeat_search = '<enter>',
next_phase_one_target = '<enter>',
next_target = {'<enter>', ';'},
prev_target = {'<tab>', ','},
next_group = '<space>',
prev_group = '<tab>',
multi_accept = '<enter>',
multi_revert = '<backspace>',
},
}
'';
};
vim.maps.operator = mkMerge [ binds.whichKey.register."<leader>s" = mkDefault "+Leap";
(mkBinding cfg.mappings.leapForwardTo "<Plug>(leap-forward-to)" "Leap forward to") };
(mkBinding cfg.mappings.leapBackwardTo "<Plug>(leap-backward-to)" "Leap backward to")
(mkBinding cfg.mappings.leapForwardTill "<Plug>(leap-forward-till)" "Leap forward till")
(mkBinding cfg.mappings.leapBackwardTill "<Plug>(leap-backward-till)" "Leap backward till")
(mkBinding cfg.mappings.leapFromWindow "<Plug>(leap-from-window)" "Leap from window")
];
vim.maps.visualOnly = mkMerge [
(mkBinding cfg.mappings.leapForwardTo "<Plug>(leap-forward-to)" "Leap forward to")
(mkBinding cfg.mappings.leapBackwardTo "<Plug>(leap-backward-to)" "Leap backward to")
(mkBinding cfg.mappings.leapForwardTill "<Plug>(leap-forward-till)" "Leap forward till")
(mkBinding cfg.mappings.leapBackwardTill "<Plug>(leap-backward-till)" "Leap backward till")
(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,
highlight_unlabeled_phase_one_targets = false,
max_highlighted_traversal_targets = 10,
case_sensitive = false,
equivalence_classes = { ' \t\r\n', },
substitute_chars = {},
safe_labels = {
"s", "f", "n", "u", "t", "/",
"S", "F", "N", "L", "H", "M", "U", "G", "T", "?", "Z"
},
labels = {
"s", "f", "n",
"j", "k", "l", "h", "o", "d", "w", "e", "m", "b",
"u", "y", "v", "r", "g", "t", "c", "x", "/", "z",
"S", "F", "N",
"J", "K", "L", "H", "O", "D", "W", "E", "M", "B",
"U", "Y", "V", "R", "G", "T", "C", "X", "?", "Z"
},
special_keys = {
repeat_search = '<enter>',
next_phase_one_target = '<enter>',
next_target = {'<enter>', ';'},
prev_target = {'<tab>', ','},
next_group = '<space>',
prev_group = '<tab>',
multi_accept = '<enter>',
multi_revert = '<backspace>',
},
}
'';
}; };
} }

View file

@ -0,0 +1,18 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.vim.utility.motion.precognition;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["precognition-nvim"];
luaConfigRC.precognition = lib.nvim.dag.entryAnywhere ''
require('precognition').setup(${lib.nvim.lua.toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,66 @@
{lib, ...}: let
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.types) attrsOf listOf str bool int submodule;
inherit (lib.nvim.types) mkPluginSetupOption;
mkHintType = description:
mkOption {
inherit description;
default = {};
type = attrsOf (submodule {
options = {
text = mkOption {
type = str;
description = "The easier-to-read depiction of the motion";
};
prio = mkOption {
type = int;
default = 1;
description = "The priority of the hint";
example = 10;
};
};
});
};
in {
options.vim.utility.motion.precognition = {
enable = mkEnableOption "assisted motion discovery[precognition.nvim]";
setupOpts = mkPluginSetupOption "precognition.nvim" {
startVisible = mkOption {
type = bool;
default = true;
description = "Whether to start 'precognition' automatically";
};
showBlankVirtLine = mkOption {
type = bool;
default = true;
description = "Whether to show a blank virtual line when no movements are shown";
};
highlightColor = mkOption {
type = attrsOf str;
default = {link = "Comment";};
example = literalExpression ''
{ link = "Comment"; }
# or
{ foreground = "#0000FF"; background = "#000000"; };
'';
description = "The highlight for the virtual text";
};
disabled_fts = mkOption {
type = listOf str;
default = ["startify"];
example = literalExpression ''["startify"]'';
description = "Filetypes that automatically disable 'precognition'";
};
hints = mkHintType "What motions display, and at what priority";
gutterHints = mkHintType ''
What motions display and at what priority. Only appears in gutters
'';
};
};
}

View file

@ -8,24 +8,47 @@
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.utility.surround; cfg = config.vim.utility.surround;
mkLznKey = mode: key: {
inherit key mode;
};
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = ["nvim-surround"]; startPlugins = ["nvim-surround"];
pluginRC.surround = entryAnywhere "require('nvim-surround').setup(${toLuaObject cfg.setupOpts})"; pluginRC.surround = entryAnywhere "require('nvim-surround').setup(${toLuaObject cfg.setupOpts})";
utility.surround.setupOpts.keymaps = mkIf cfg.useVendoredKeybindings { lazy.plugins.nvim-surround = {
insert = "<C-g>z"; package = "nvim-surround";
insert_line = "<C-g>Z"; setupModule = "nvim-surround";
normal = "gz"; inherit (cfg) setupOpts;
normal_cur = "gZ";
normal_line = "gzz"; keys =
normal_cur_line = "gZZ"; [
visual = "gz"; (mkLznKey ["i"] cfg.setupOpts.keymaps.insert)
visual_line = "gZ"; (mkLznKey ["i"] cfg.setupOpts.keymaps.insert_line)
delete = "gzd"; (mkLznKey ["x"] cfg.setupOpts.keymaps.visual)
change = "gzr"; (mkLznKey ["x"] cfg.setupOpts.keymaps.visual_line)
change_line = "gZR"; (mkLznKey ["n"] cfg.setupOpts.keymaps.normal)
(mkLznKey ["n"] cfg.setupOpts.keymaps.normal_cur)
(mkLznKey ["n"] cfg.setupOpts.keymaps.normal_line)
(mkLznKey ["n"] cfg.setupOpts.keymaps.normal_cur_line)
(mkLznKey ["n"] cfg.setupOpts.keymaps.delete)
(mkLznKey ["n"] cfg.setupOpts.keymaps.change)
(mkLznKey ["n"] cfg.setupOpts.keymaps.change_line)
]
++ map (mkLznKey ["n" "i" "v"]) [
"<Plug>(nvim-surround-insert)"
"<Plug>(nvim-surround-insert-line)"
"<Plug>(nvim-surround-normal)"
"<Plug>(nvim-surround-normal-cur)"
"<Plug>(nvim-surround-normal-line)"
"<Plug>(nvim-surround-normal-cur-line)"
"<Plug>(nvim-surround-visual)"
"<Plug>(nvim-surround-visual-line)"
"<Plug>(nvim-surround-delete)"
"<Plug>(nvim-surround-change)"
"<Plug>(nvim-surround-change-line)"
];
}; };
}; };
}; };

View file

@ -1,7 +1,36 @@
{lib, ...}: let {
lib,
config,
...
}: let
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.types) bool; inherit (lib.types) bool str;
inherit (lib.nvim.types) mkPluginSetupOption; inherit (lib.nvim.types) mkPluginSetupOption;
cfg = config.vim.utility.surround;
vendoredKeybinds = {
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";
};
mkKeymapOption = name: default:
mkOption {
description = "keymap for ${name}";
type = str;
default =
if cfg.useVendoredKeybindings
then vendoredKeybinds.${name}
else default;
};
in { in {
options.vim.utility.surround = { options.vim.utility.surround = {
enable = mkOption { enable = mkOption {
@ -13,7 +42,21 @@ in {
with nvim-leap. with nvim-leap.
''; '';
}; };
setupOpts = mkPluginSetupOption "nvim-surround" {}; setupOpts = mkPluginSetupOption "nvim-surround" {
keymaps = {
insert = mkKeymapOption "insert" "<C-g>s";
insert_line = mkKeymapOption "insert_line" "<C-g>S";
normal = mkKeymapOption "normal" "ys";
normal_cur = mkKeymapOption "normal_cur" "yss";
normal_line = mkKeymapOption "normal_line" "yS";
normal_cur_line = mkKeymapOption "normal_cur_line" "ySS";
visual = mkKeymapOption "visual" "S";
visual_line = mkKeymapOption "visual_line" "gS";
delete = mkKeymapOption "delete" "ds";
change = mkKeymapOption "change" "cs";
change_line = mkKeymapOption "change_line" "cS";
};
};
useVendoredKeybindings = mkOption { useVendoredKeybindings = mkOption {
type = bool; type = bool;

View file

@ -1,63 +1,72 @@
{ {
options,
config, config,
pkgs,
lib, lib,
... ...
}: let }: let
inherit (lib.modules) mkIf mkMerge; inherit (lib.modules) mkIf;
inherit (lib.nvim.binds) addDescriptionsToMappings mkSetBinding; inherit (lib.nvim.binds) addDescriptionsToMappings;
inherit (lib.nvim.dag) entryAnywhere; inherit (lib.strings) optionalString;
inherit (lib.nvim.binds) pushDownDefault; inherit (lib.lists) optionals;
inherit (lib.nvim.lua) toLuaObject; inherit (lib.nvim.binds) pushDownDefault mkSetLznBinding;
cfg = config.vim.telescope; cfg = config.vim.telescope;
self = import ./telescope.nix {inherit pkgs lib;}; mappingDefinitions = options.vim.telescope.mappings;
mappingDefinitions = self.options.vim.telescope.mappings;
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions; mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
in { in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
vim = { vim = {
startPlugins = [ startPlugins = ["plenary-nvim"];
"telescope"
"plenary-nvim"
];
maps.normal = mkMerge [ lazy.plugins.telescope = {
(mkSetBinding mappings.findFiles "<cmd> Telescope find_files<CR>") package = "telescope";
(mkSetBinding mappings.liveGrep "<cmd> Telescope live_grep<CR>") setupModule = "telescope";
(mkSetBinding mappings.buffers "<cmd> Telescope buffers<CR>") inherit (cfg) setupOpts;
(mkSetBinding mappings.helpTags "<cmd> Telescope help_tags<CR>") after = ''
(mkSetBinding mappings.open "<cmd> Telescope<CR>") local telescope = require("telescope")
(mkSetBinding mappings.resume "<cmd> Telescope resume<CR>") ${optionalString config.vim.ui.noice.enable "telescope.load_extension('noice')"}
${optionalString config.vim.notify.nvim-notify.enable "telescope.load_extension('notify')"}
${optionalString config.vim.projects.project-nvim.enable "telescope.load_extension('projects')"}
'';
(mkSetBinding mappings.gitCommits "<cmd> Telescope git_commits<CR>") cmd = ["Telescope"];
(mkSetBinding mappings.gitBufferCommits "<cmd> Telescope git_bcommits<CR>")
(mkSetBinding mappings.gitBranches "<cmd> Telescope git_branches<CR>")
(mkSetBinding mappings.gitStatus "<cmd> Telescope git_status<CR>")
(mkSetBinding mappings.gitStash "<cmd> Telescope git_stash<CR>")
(mkIf config.vim.lsp.enable (mkMerge [ keys =
(mkSetBinding mappings.lspDocumentSymbols "<cmd> Telescope lsp_document_symbols<CR>") [
(mkSetBinding mappings.lspWorkspaceSymbols "<cmd> Telescope lsp_workspace_symbols<CR>") (mkSetLznBinding mappings.findFiles "<cmd> Telescope find_files<CR>")
(mkSetLznBinding mappings.liveGrep "<cmd> Telescope live_grep<CR>")
(mkSetLznBinding mappings.buffers "<cmd> Telescope buffers<CR>")
(mkSetLznBinding mappings.helpTags "<cmd> Telescope help_tags<CR>")
(mkSetLznBinding mappings.open "<cmd> Telescope<CR>")
(mkSetBinding mappings.lspReferences "<cmd> Telescope lsp_references<CR>") (mkSetLznBinding mappings.gitCommits "<cmd> Telescope git_commits<CR>")
(mkSetBinding mappings.lspImplementations "<cmd> Telescope lsp_implementations<CR>") (mkSetLznBinding mappings.gitBufferCommits "<cmd> Telescope git_bcommits<CR>")
(mkSetBinding mappings.lspDefinitions "<cmd> Telescope lsp_definitions<CR>") (mkSetLznBinding mappings.gitBranches "<cmd> Telescope git_branches<CR>")
(mkSetBinding mappings.lspTypeDefinitions "<cmd> Telescope lsp_type_definitions<CR>") (mkSetLznBinding mappings.gitStatus "<cmd> Telescope git_status<CR>")
(mkSetBinding mappings.diagnostics "<cmd> Telescope diagnostics<CR>") (mkSetLznBinding mappings.gitStash "<cmd> Telescope git_stash<CR>")
])) ]
++ (optionals config.vim.lsp.enable [
(mkSetLznBinding mappings.lspDocumentSymbols "<cmd> Telescope lsp_document_symbols<CR>")
(mkSetLznBinding mappings.lspWorkspaceSymbols "<cmd> Telescope lsp_workspace_symbols<CR>")
( (mkSetLznBinding mappings.lspReferences "<cmd> Telescope lsp_references<CR>")
mkIf config.vim.treesitter.enable (mkSetLznBinding mappings.lspImplementations "<cmd> Telescope lsp_implementations<CR>")
(mkSetBinding mappings.treesitter "<cmd> Telescope treesitter<CR>") (mkSetLznBinding mappings.lspDefinitions "<cmd> Telescope lsp_definitions<CR>")
) (mkSetLznBinding mappings.lspTypeDefinitions "<cmd> Telescope lsp_type_definitions<CR>")
(mkSetLznBinding mappings.diagnostics "<cmd> Telescope diagnostics<CR>")
( ])
mkIf config.vim.projects.project-nvim.enable ++ (
(mkSetBinding mappings.findProjects "<cmd> Telescope projects<CR>") optionals config.vim.treesitter.enable [
) (mkSetLznBinding mappings.treesitter "<cmd> Telescope treesitter<CR>")
]; ]
)
++ (
optionals config.vim.projects.project-nvim.enable [
(mkSetLznBinding mappings.findProjects "<cmd Telescope projects<CR>")
]
);
};
binds.whichKey.register = pushDownDefault { binds.whichKey.register = pushDownDefault {
"<leader>f" = "+Telescope"; "<leader>f" = "+Telescope";
@ -66,29 +75,6 @@ in {
"<leader>fv" = "Telescope Git"; "<leader>fv" = "Telescope Git";
"<leader>fvc" = "Commits"; "<leader>fvc" = "Commits";
}; };
pluginRC.telescope = entryAnywhere ''
local telescope = require('telescope')
telescope.setup(${toLuaObject cfg.setupOpts})
${
if config.vim.ui.noice.enable
then "telescope.load_extension('noice')"
else ""
}
${
if config.vim.notify.nvim-notify.enable
then "telescope.load_extension('notify')"
else ""
}
${
if config.vim.projects.project-nvim.enable
then "telescope.load_extension('projects')"
else ""
}
'';
}; };
}; };
} }

View file

@ -0,0 +1,60 @@
{lib, ...}: let
inherit (lib.modules) mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.nvim.types) luaInline;
inherit (lib.nvim.binds) mkMappingOption;
inherit (lib.generators) mkLuaInline;
in {
imports = [
(mkRenamedOptionModule ["vim" "visuals" "cellularAutomaton"] ["vim" "visuals" "cellular-automaton"])
];
options.vim.visuals.cellular-automaton = {
enable = mkEnableOption "cellular-automaton to help you cope with stubborn code [cellular-automaton]";
mappings = {
makeItRain = mkMappingOption "Make it rain [cellular-automaton]" "<leader>fml";
};
animation = {
register = mkEnableOption "registering configured animation(s) automatically" // {default = true;};
setup = mkOption {
type = luaInline;
default = mkLuaInline ''
local ca_config = {
fps = 50,
name = 'slide',
}
-- init function is invoked only once at the start
-- config.init = function (grid)
--
-- end
-- update function
ca_config.update = function (grid)
for i = 1, #grid do
local prev = grid[i][#(grid[i])]
for j = 1, #(grid[i]) do
grid[i][j], prev = prev, grid[i][j]
end
end
return true
end
'';
description = ''
Configuration used to generate an animation to be registered.
The final value for `ca_config` will be used to register a new
animation using `require("cellular-automaton").register_animation(ca_config)`
::: {.warning}
`ca_config` **must** eval to a valid Lua table. nvf does not and cannot
perform any kind of validation on your Lua code, so bogus values will
result in errors when the animation is registered.
:::
'';
};
};
};
}

View file

@ -0,0 +1,39 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.strings) optionalString;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere entryAfter;
inherit (lib.nvim.binds) mkBinding;
cfg = config.vim.visuals.cellular-automaton;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["cellular-automaton"];
maps.normal = mkBinding cfg.mappings.makeItRain "<cmd>CellularAutomaton make_it_rain<CR>" "Make it rain";
pluginRC = {
# XXX: This has no error handling. User can set
# `animation.setup` to a bogus value, and we would
# have an error in our hands. I don't think there
# is a good way to check for errors, so I'm leaving
# it like this under the assumption that the user
# will not mess it up for no reason.
cellular-automaton-anim = entryAnywhere (optionalString cfg.animation.register ''
-- Coerce user animation config into pluginRC
${toLuaObject cfg.animation.setup}
'');
cellular-automaton = entryAfter ["cellular-automaton-anim"] ''
-- Register the animation
require("cellular-automaton").register_animation(ca_config)
'';
};
};
};
}

View file

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

View file

@ -0,0 +1,35 @@
{lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) submodule attrs attrsOf;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
imports = [
(mkRemovedOptionModule ["vim" "visuals" "smoothScroll"] ''
`vim.visuals.smoothScroll` has been removed. You may consider enabling the
option `vim.visuals.cinnamon-nvim` to repliace previous smooth scrolling
behaviour.
'')
];
options.vim.visuals.cinnamon-nvim = {
enable = mkEnableOption "smooth scrolling for ANY command [cinnamon-nvim]";
setupOpts = mkPluginSetupOption "cinnamon.nvim" {
options = mkOption {
type = attrs;
default = {
# Defaults provided for the sake of documentation only!
# Who would've guessed setupOpts.options would be confusing?
mode = "cursor";
count_only = false;
};
description = "Scroll options";
};
keymaps = {
basic = mkEnableOption "basic animation keymaps";
extra = mkEnableOption "extra animation keymaps";
};
};
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.cinnamon-nvim;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["cinnamon-nvim"];
pluginRC.cursorline = entryAnywhere ''
require("cinnamon").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -1,118 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.trivial) boolToString;
inherit (lib.nvim.binds) mkBinding;
inherit (lib.nvim.dag) entryAnywhere;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.visuals;
in {
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.indentBlankline.enable {
vim.startPlugins = ["indent-blankline"];
vim.pluginRC.indent-blankline = entryAnywhere ''
require("ibl").setup(${toLuaObject cfg.indentBlankline.setupOpts})
'';
})
(mkIf cfg.cursorline.enable {
vim.startPlugins = ["nvim-cursorline"];
vim.pluginRC.cursorline = entryAnywhere ''
require('nvim-cursorline').setup {
cursorline = {
timeout = ${toString cfg.cursorline.lineTimeout},
number = ${boolToString (!cfg.cursorline.lineNumbersOnly)},
}
}
'';
})
(mkIf cfg.nvimWebDevicons.enable {
vim.startPlugins = ["nvim-web-devicons"];
})
(mkIf cfg.scrollBar.enable {
vim.startPlugins = ["scrollbar-nvim"];
vim.pluginRC.scrollBar = entryAnywhere ''
require('scrollbar').setup{
excluded_filetypes = {
'prompt',
'TelescopePrompt',
'noice',
'NvimTree',
'alpha',
'notify',
'Navbuddy'
},
}
'';
})
(mkIf cfg.smoothScroll.enable {
vim.startPlugins = ["cinnamon-nvim"];
vim.pluginRC.smoothScroll = entryAnywhere ''
require('cinnamon').setup()
'';
})
(mkIf cfg.cellularAutomaton.enable {
vim.startPlugins = ["cellular-automaton"];
vim.maps.normal = mkBinding cfg.cellularAutomaton.mappings.makeItRain "<cmd>CellularAutomaton make_it_rain<CR>" "Make it rain";
vim.pluginRC.cellularAUtomaton = entryAnywhere ''
local config = {
fps = 50,
name = 'slide',
}
-- init function is invoked only once at the start
-- config.init = function (grid)
--
-- end
-- update function
config.update = function (grid)
for i = 1, #grid do
local prev = grid[i][#(grid[i])]
for j = 1, #(grid[i]) do
grid[i][j], prev = prev, grid[i][j]
end
end
return true
end
require("cellular-automaton").register_animation(config)
'';
})
(mkIf cfg.highlight-undo.enable {
vim.startPlugins = ["highlight-undo"];
vim.pluginRC.highlight-undo = entryAnywhere ''
require('highlight-undo').setup({
duration = ${toString cfg.highlight-undo.duration},
highlight_for_count = ${boolToString cfg.highlight-undo.highlightForCount},
undo = {
hlgroup = ${cfg.highlight-undo.undo.hlGroup},
mode = 'n',
lhs = 'u',
map = 'undo',
opts = {}
},
redo = {
hlgroup = ${cfg.highlight-undo.redo.hlGroup},
mode = 'n',
lhs = '<C-r>',
map = 'redo',
opts = {}
},
})
'';
})
]);
}

View file

@ -1,7 +1,19 @@
{...}: { {lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule;
in {
imports = [ imports = [
./config.nix (mkRemovedOptionModule ["vim" "visuals" "enable"] ''
./visuals.nix As top-level toggles are being deprecated, you are encouraged
./fidget to handle plugin toggles under individual options.
'')
./cellular-automaton
./cinnamon-nvim
./fidget-nvim
./highlight-undo
./indent-blankline
./nvim-cursorline
./nvim-scrollbar
./nvim-web-devicons
]; ];
} }

View file

@ -0,0 +1,18 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
cfg = config.vim.visuals.fidget-nvim;
in {
config = mkIf cfg.enable {
vim.lazy.plugins.fidget-nvim = {
package = "fidget-nvim";
setupModule = "fidget";
event = "LspAttach";
inherit (cfg) setupOpts;
};
};
}

View file

@ -12,8 +12,11 @@
in { in {
imports = [ imports = [
(mkRenamedOptionModule ["vim" "visuals" "fidget-nvim" "align" "bottom"] ["vim" "visuals" "fidget-nvim" "setupOpts" "notification" "window" "align"]) (mkRenamedOptionModule ["vim" "visuals" "fidget-nvim" "align" "bottom"] ["vim" "visuals" "fidget-nvim" "setupOpts" "notification" "window" "align"])
(mkRemovedOptionModule ["vim" "visuals" "fidget-nvim" "align" "right"] (mkRemovedOptionModule ["vim" "visuals" "fidget-nvim" "align" "right"] ''
"Option `vim.fidget-nvim.align.right` has been removed and does not have an equivalent replacement in rewritten fidget.nvim configuration.") Option `vim.fidget-nvim.align.right` has been removed and does not have an
equivalent replacement in rewritten fidget.nvim configuration. Please remove
it from your configuration.
'')
]; ];
options.vim.visuals.fidget-nvim = { options.vim.visuals.fidget-nvim = {

View file

@ -1,19 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.fidget-nvim;
in {
config = mkIf cfg.enable {
vim.startPlugins = ["fidget-nvim"];
vim.pluginRC.fidget-nvim = entryAnywhere ''
require'fidget'.setup(${toLuaObject cfg.setupOpts})
'';
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.highlight-undo;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["highlight-undo"];
pluginRC.highlight-undo = entryAnywhere ''
require("highlight-undo").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,32 @@
{lib, ...}: let
inherit (lib.modules) mkRemovedOptionModule;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) int;
inherit (lib.nvim.types) mkPluginSetupOption;
checkDocsMsg = ''
highlight-undo.nvim has deprecated previously used configuration options in
a recent update, so previous values will no longer work as expected.
Please use `vim.visuals.highlight-undo.setupOpts` with upstream instructions
'';
in {
imports = [
# This gives a lot of error messages for those with default values set or modified. Could
# there be a better way to handle his? Perhaps an assertion?
(mkRemovedOptionModule ["vim" "visuals" "highlight-undo" "highlightForCount"] checkDocsMsg)
(mkRemovedOptionModule ["vim" "visuals" "highlight-undo" "undo" "hlGroup"] checkDocsMsg)
(mkRemovedOptionModule ["vim" "visuals" "highlight-undo" "redo" "hlGroup"] checkDocsMsg)
];
options.vim.visuals.highlight-undo = {
enable = mkEnableOption "highlight undo [highlight-undo]";
setupOpts = mkPluginSetupOption "highlight-undo" {
duration = mkOption {
type = int;
default = 500;
description = "Duration of the highlight";
};
};
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.indent-blankline;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["indent-blankline"];
pluginRC.indent-blankline = entryAnywhere ''
require("ibl").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,195 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) int bool str nullOr either listOf attrsOf;
cfg = config.vim.visuals;
in {
imports = [
(mkRenamedOptionModule ["vim" "visuals" "indentBlankline"] ["vim" "visuals" "indent-blankline"])
];
options.vim.visuals.indent-blankline = {
enable = mkEnableOption "indentation guides [indent-blankline]";
setupOpts = {
debounce = mkOption {
type = int;
description = "Debounce time in milliseconds";
default = 200;
};
viewport_buffer = {
min = mkOption {
type = int;
description = "Number of lines above and below of what is currently
visible in the window";
default = 30;
};
max = mkOption {
type = int;
description = "Number of lines above and below of what is currently
visible in the window";
default = 500;
};
};
indent = {
char = mkOption {
type = either str (listOf str);
description = "Character(s) for indentation guide";
default = "";
};
tab_char = mkOption {
type = nullOr (either str (listOf str));
description = ''
Character(s) for tab indentation guide.
See `:help ibl.config.indent.tab_char`.
'';
default = null;
};
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to the indentation guide.
See `:help ibl.config.indent.highlight`.
'';
default = null;
};
smart_indent_cap = mkOption {
type = bool;
description = "Caps the number of indentation levels based on surrounding code";
default = true;
};
priority = mkOption {
type = int;
description = "Virtual text priority for the indentation guide";
default = 1;
};
repeat_linebreak = mkOption {
type = bool;
description = "Repeat indentation guides on wrapped lines";
default = true;
};
};
whitespace = {
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to whitespace.
See `:help ibl.config.whitespace.highlight`.
'';
default = null;
};
remove_blankline_trail = mkOption {
type = bool;
description = "Remove trailing whitespace on blanklines";
default = true;
};
};
scope = {
enabled = mkOption {
description = "Highlight current scope from treesitter";
type = bool;
default = config.vim.treesitter.enable;
defaultText = literalExpression "config.vim.treesitter.enable";
};
char = mkOption {
type = either str (listOf str);
description = "The character(s) for the scope indentation guide";
default = cfg.indent-blankline.setupOpts.indent.char;
defaultText = literalExpression "config.vim.visuals.indent-blankline.setupOpts.indent.char";
};
show_start = mkOption {
type = bool;
description = "Show an underline on the first line of the scope";
default = false;
};
show_end = mkOption {
type = bool;
description = "Show an underline on the last line of the scope";
default = false;
};
show_exact_scope = mkOption {
type = bool;
description = "Show the scope underline at the exact start of the scope, even if that's to the right of the indentation guide";
default = false;
};
injected_languages = mkOption {
type = bool;
description = "Check for injected languages (treesitter)";
default = config.vim.treesitter.enable;
defaultText = literalExpression "config.vim.treesitter.enable";
};
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to the scope.
See `:help `ibl.config.scope.highlight`.
'';
default = null;
};
priority = mkOption {
type = int;
description = "Virtual text priority for the scope";
default = 1024;
};
include.node_type = mkOption {
type = attrsOf (listOf str);
description = "Additional nodes to be used for scope checking, per language";
default = {};
};
exclude = {
language = mkOption {
type = listOf str;
description = ''
The list of treesitter languages to disable scope for.
`*` can be used as a wildcard for every language/node type.
'';
default = [];
};
node_type = mkOption {
type = attrsOf (listOf str);
description = ''
Nodes to ignore in scope checking, per language.
`*` can be used as a wildcard for every language.
'';
default = {
"*" = ["source_file" "program"];
lua = ["chunk"];
python = ["module"];
};
};
};
};
};
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.nvim-cursorline;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["nvim-cursorline"];
pluginRC.nvim-cursorline = entryAnywhere ''
require("nvim-cursorline").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,65 @@
{lib, ...}: let
inherit (lib.modules) mkRenamedOptionModule mkRemovedOptionModule;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) int bool;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
imports = [
(mkRenamedOptionModule ["vim" "visuals" "cursorline"] ["vim" "visuals" "nvim-cursorline"])
(mkRenamedOptionModule ["vim" "visuals" "nvim-cursorline" "lineTimeout"] ["vim" "visuals" "nvim-cursorline" "setupOpts" "line_timeout"])
(mkRemovedOptionModule ["vim" "visuals" "nvim-cursorline" "lineNumbersOnly"] ''
`vim.visuals.nvim-cursorline.lineNumbersOnly` has been removed. Use `vim.visuals.nvim-cursorline.number` instead.
'')
];
options.vim.visuals.nvim-cursorline = {
enable = mkEnableOption "cursor word and line highlighting [nvim-cursorline]";
# Upstream has **zero** documentation whatsoever. I'm making wild assumptions
# on what goes into description based don the source code. I'm sorry. Not.
setupOpts = mkPluginSetupOption "nvim-cursorline" {
cursorline = {
enable = mkEnableOption "cursor line highlighting";
timeout = mkOption {
type = int;
default = 1000;
description = "Cursorline timeout";
};
number = mkOption {
type = bool;
default = false;
description = ''
If true, `vim.wo.cursorlineopt` will be set to "number"
when the trigger conditions are met.
'';
};
};
cursorword = {
enable = mkEnableOption "cursor word highlighting";
timeout = mkOption {
type = int;
default = 1000;
description = "Cursorword timeout";
};
min_length = mkOption {
type = int;
default = 3;
description = ''
The min_length option defines the minimum number of characters
a word must have to be highlighted as a "cursor word." Any word
shorter than this value will be ignored and not highlighted.
'';
};
hl.underline = mkOption {
type = bool;
default = true;
description = "Whether to underline matching cursorword";
};
};
};
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.nvim-scrollbar;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["nvim-scrollbar"];
pluginRC.cursorline = entryAnywhere ''
require("scrollbar").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,21 @@
{lib, ...}: let
inherit (lib.modules) mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) listOf str;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
imports = [
(mkRenamedOptionModule ["vim" "visuals" "scrollBar"] ["vim" "visuals" "nvim-scrollbar"])
];
options.vim.visuals.nvim-scrollbar = {
enable = mkEnableOption "extensible Neovim Scrollbar [nvim-scrollbar]";
setupOpts = mkPluginSetupOption "scrollbar-nvim" {
excluded_filetypes = mkOption {
type = listOf str;
default = ["prompt" "TelescopePrompt" "noice" "noice" "NvimTree" "neo-tree" "alpha" "notify" "Navbuddy"];
description = "Filetypes to hide the scrollbar on";
};
};
};
}

View file

@ -0,0 +1,21 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkIf;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryAnywhere;
cfg = config.vim.visuals.nvim-web-devicons;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["nvim-web-devicons"];
pluginRC.nvim-web-devicons = entryAnywhere ''
require("nvim-web-devicons").setup(${toLuaObject cfg.setupOpts})
'';
};
};
}

View file

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

View file

@ -0,0 +1,48 @@
{
config,
lib,
...
}: let
inherit (lib.modules) mkRenamedOptionModule;
inherit (lib.options) mkOption mkEnableOption literalExpression;
inherit (lib.types) nullOr attrsOf attrs enum;
inherit (lib.nvim.types) mkPluginSetupOption;
in {
imports = [
(mkRenamedOptionModule ["vim" "visuals" "nvimWebDevicons"] ["vim" "visuals" "nvim-web-devicons"])
];
options.vim.visuals.nvim-web-devicons = {
enable = mkEnableOption "Neovim dev icons [nvim-web-devicons]";
setupOpts = mkPluginSetupOption "nvim-web-devicons" {
color_icons = mkEnableOption "different highlight colors per icon";
variant = mkOption {
type = nullOr (enum ["light" "dark"]);
default = null;
description = "Set the light or dark variant manually, instead of relying on `background`";
};
override = mkOption {
type = attrsOf attrs;
default = {};
example = literalExpression ''
{
zsh = {
name = "Zsh";
icon = "";
color = "#428850";
cterm_color = "65";
};
}
'';
description = ''
Your personal icon overrides.
You can specify color or cterm_color instead of specifying
both of them. DevIcon will be appended to `name`
'';
};
};
};
}

View file

@ -1,261 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkEnableOption mkOption literalExpression;
inherit (lib.types) int bool str nullOr either listOf attrsOf;
inherit (lib.nvim.binds) mkMappingOption;
cfg = config.vim.visuals;
in {
options.vim.visuals = {
enable = mkEnableOption "Visual enhancements.";
nvimWebDevicons.enable = mkEnableOption "dev icons. Required for certain plugins [nvim-web-devicons].";
scrollBar.enable = mkEnableOption "scrollbar [scrollbar.nvim]";
smoothScroll.enable = mkEnableOption "smooth scrolling [cinnamon-nvim]";
cellularAutomaton = {
enable = mkEnableOption "cellular automaton [cellular-automaton]";
mappings = {
makeItRain = mkMappingOption "Make it rain [cellular-automaton]" "<leader>fml";
};
};
cursorline = {
enable = mkEnableOption "line hightlighting on the cursor [nvim-cursorline]";
lineTimeout = mkOption {
type = int;
description = "Time in milliseconds for cursorline to appear";
default = 0;
};
lineNumbersOnly = mkOption {
type = bool;
description = "Hightlight only in the presence of line numbers";
default = true;
};
};
indentBlankline = {
enable = mkEnableOption "indentation guides [indent-blankline]";
setupOpts = {
debounce = mkOption {
type = int;
description = "Debounce time in milliseconds";
default = 200;
};
viewport_buffer = {
min = mkOption {
type = int;
description = "Number of lines above and below of what is currently
visible in the window";
default = 30;
};
max = mkOption {
type = int;
description = "Number of lines above and below of what is currently
visible in the window";
default = 500;
};
};
indent = {
char = mkOption {
type = either str (listOf str);
description = "Character(s) for indentation guide";
default = "";
};
tab_char = mkOption {
type = nullOr (either str (listOf str));
description = ''
Character(s) for tab indentation guide.
See `:help ibl.config.indent.tab_char`.
'';
default = null;
};
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to the indentation guide.
See `:help ibl.config.indent.highlight`.
'';
default = null;
};
smart_indent_cap = mkOption {
type = bool;
description = "Caps the number of indentation levels based on surrounding code";
default = true;
};
priority = mkOption {
type = int;
description = "Virtual text priority for the indentation guide";
default = 1;
};
repeat_linebreak = mkOption {
type = bool;
description = "Repeat indentation guides on wrapped lines";
default = true;
};
};
whitespace = {
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to whitespace.
See `:help ibl.config.whitespace.highlight`.
'';
default = null;
};
remove_blankline_trail = mkOption {
type = bool;
description = "Remove trailing whitespace on blanklines";
default = true;
};
};
scope = {
enabled = mkOption {
description = "Highlight current scope from treesitter";
type = bool;
default = config.vim.treesitter.enable;
defaultText = literalExpression "config.vim.treesitter.enable";
};
char = mkOption {
type = either str (listOf str);
description = "The character(s) for the scope indentation guide";
default = cfg.indentBlankline.setupOpts.indent.char;
defaultText = literalExpression "config.vim.visuals.indentBlankline.setuopOpts.indent.char";
};
show_start = mkOption {
type = bool;
description = "Show an underline on the first line of the scope";
default = false;
};
show_end = mkOption {
type = bool;
description = "Show an underline on the last line of the scope";
default = false;
};
show_exact_scope = mkOption {
type = bool;
description = "Show the scope underline at the exact start of the scope, even if that's to the right of the indentation guide";
default = false;
};
injected_languages = mkOption {
type = bool;
description = "Check for injected languages (treesitter)";
default = config.vim.treesitter.enable;
defaultText = literalExpression "config.vim.treesitter.enable";
};
highlight = mkOption {
type = nullOr (either str (listOf str));
description = ''
The highlight group(s) applied to the scope.
See `:help `ibl.config.scope.highlight`.
'';
default = null;
};
priority = mkOption {
type = int;
description = "Virtual text priority for the scope";
default = 1024;
};
include.node_type = mkOption {
type = attrsOf (listOf str);
description = "Additional nodes to be used for scope checking, per language";
default = {};
};
exclude = {
language = mkOption {
type = listOf str;
description = ''
The list of treesitter languages to disable scope for.
`*` can be used as a wildcard for every language/node type.
'';
default = [];
};
node_type = mkOption {
type = attrsOf (listOf str);
description = ''
Nodes to ignore in scope checking, per language.
`*` can be used as a wildcard for every language.
'';
default = {
"*" = ["source_file" "program"];
lua = ["chunk"];
python = ["module"];
};
};
};
};
};
};
highlight-undo = {
enable = mkEnableOption "highlight undo [highlight-undo]";
highlightForCount = mkOption {
type = bool;
default = true;
description = ''
Enable support for highlighting when a <count> is provided before the key
If set to false it will only highlight when the mapping is not prefixed with a <count>
'';
};
duration = mkOption {
type = int;
description = "Duration of highlight";
default = 500;
};
undo = {
hlGroup = mkOption {
type = str;
description = "Highlight group for undo";
default = "HighlightUndo";
};
};
redo = {
hlGroup = mkOption {
type = str;
description = "Highlight group for redo";
default = "HighlightUndo";
};
};
};
};
}

View file

@ -0,0 +1,108 @@
{
lib,
config,
...
}: let
inherit (builtins) toJSON typeOf head length filter concatLists concatStringsSep;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.modules) mkIf mkMerge;
inherit (lib.generators) mkLuaInline;
inherit (lib.strings) optionalString;
inherit (lib.nvim.lua) toLuaObject;
inherit (lib.nvim.dag) entryBefore entryAfter;
cfg = config.vim.lazy;
toLuaLznKeySpec = keySpec:
(removeAttrs keySpec ["key" "lua" "action"])
// {
"@1" = keySpec.key;
"@2" =
if keySpec.lua
then mkLuaInline keySpec.action
else keySpec.action;
};
toLuaLznSpec = name: spec:
(removeAttrs spec ["package" "setupModule" "setupOpts" "keys"])
// {
"@1" = name;
before =
if spec.before != null
then
mkLuaInline ''
function()
${spec.before}
end
''
else null;
after =
if spec.setupModule == null && spec.after == null
then null
else
mkLuaInline ''
function()
${
optionalString (spec.setupModule != null)
"require(${toJSON spec.setupModule}).setup(${toLuaObject spec.setupOpts})"
}
${optionalString (spec.after != null) spec.after}
end
'';
keys =
if typeOf spec.keys == "list" && length spec.keys > 0 && typeOf (head spec.keys) == "set"
then map toLuaLznKeySpec (filter (keySpec: keySpec.key != null) spec.keys)
# empty list or str or (listOf str)
else spec.keys;
};
lznSpecs = mapAttrsToList toLuaLznSpec cfg.plugins;
pluginPackages = mapAttrsToList (_: plugin: plugin.package) cfg.plugins;
specToNotLazyConfig = _: spec: ''
do
${optionalString (spec.before != null) spec.before}
${optionalString (spec.setupModule != null)
"require(${toJSON spec.setupModule}).setup(${toLuaObject spec.setupOpts})"}
${optionalString (spec.after != null) spec.after}
end
'';
specToKeymaps = _: spec:
if typeOf spec.keys == "list"
then map (x: removeAttrs x ["ft"]) (filter (lznKey: lznKey.action != null && lznKey.ft == null) spec.keys)
else if spec.keys == null || typeOf spec.keys == "string"
then []
else [spec.keys];
notLazyConfig =
concatStringsSep "\n"
(mapAttrsToList specToNotLazyConfig cfg.plugins);
beforeAllJoined =
concatStringsSep "\n"
(filter (x: x != null) (mapAttrsToList (_: spec: spec.beforeAll) cfg.plugins));
in {
config.vim = mkMerge [
(mkIf cfg.enable {
startPlugins = ["lz-n" "lzn-auto-require"];
optPlugins = pluginPackages;
lazy.builtLazyConfig = ''
require('lz.n').load(${toLuaObject lznSpecs})
${optionalString cfg.enableLznAutoRequire "require('lzn-auto-require').enable()"}
'';
})
(mkIf (!cfg.enable) {
startPlugins = pluginPackages;
lazy.builtLazyConfig = ''
${beforeAllJoined}
${notLazyConfig}
'';
keymaps = concatLists (mapAttrsToList specToKeymaps cfg.plugins);
})
];
}

View file

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

View file

@ -0,0 +1,237 @@
{lib, ...}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.types) enum listOf submodule nullOr str bool int attrsOf anything either oneOf lines;
inherit (lib.nvim.types) pluginType;
inherit (lib.nvim.config) mkBool;
lznKeysSpec = submodule {
options = {
key = mkOption {
type = nullOr str;
description = "Key to bind to. If key is null this entry is ignored.";
};
action = mkOption {
type = nullOr str;
default = null;
description = "Action to trigger.";
};
lua = mkBool false ''
If true, `action` is considered to be lua code.
Thus, it will not be wrapped in `""`.
'';
desc = mkOption {
description = "Description of the key map";
type = nullOr str;
default = null;
};
ft = mkOption {
description = "TBD";
type = nullOr (listOf str);
default = null;
};
mode = mkOption {
description = "Modes to bind in";
type = either str (listOf str);
default = ["n" "x" "s" "o"];
};
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.";
};
};
lznPluginType = submodule {
options = {
package = mkOption {
type = pluginType;
description = "Plugin package";
};
setupModule = mkOption {
type = nullOr str;
description = "Lua module to run setup function on.";
default = null;
};
setupOpts = mkOption {
type = submodule {freeformType = attrsOf anything;};
description = "Options to pass to the setup function";
default = {};
};
# lz.n options
enabled = mkOption {
type = nullOr (either bool str);
description = "When false, or if the lua function returns false, this plugin will not be included in the spec";
default = null;
};
beforeAll = mkOption {
type = nullOr lines;
description = "Lua code to run before any plugins are loaded. This will be wrapped in a function.";
default = null;
};
before = mkOption {
type = nullOr lines;
description = "Lua code to run before plugin is loaded. This will be wrapped in a function.";
default = null;
};
after = mkOption {
type = nullOr lines;
description = ''
Lua code to run after plugin is loaded. This will be wrapped in a function.
If [](#opt-vim.lazy.plugins._name_.setupModule) is provided, the setup will be ran before `after`.
'';
default = null;
};
event = mkOption {
description = "Lazy-load on event";
default = null;
type = let
event = submodule {
options = {
event = mkOption {
type = nullOr (either str (listOf str));
description = "Exact event name";
example = "BufEnter";
};
pattern = mkOption {
type = nullOr (either str (listOf str));
description = "Event pattern";
example = "BufEnter *.lua";
};
};
};
in
nullOr (oneOf [str (listOf str) event]);
};
cmd = mkOption {
description = "Lazy-load on command";
default = null;
type = nullOr (either str (listOf str));
};
ft = mkOption {
description = "Lazy-load on filetype";
default = null;
type = nullOr (either str (listOf str));
};
keys = mkOption {
description = "Lazy-load on key mapping";
default = null;
type = nullOr (oneOf [str (listOf lznKeysSpec) (listOf str)]);
example = ''
keys = [
{
mode = "n";
key = "<leader>s";
action = ":DapStepOver<cr>";
desc = "DAP Step Over";
}
{
mode = ["n", "x"];
key = "<leader>dc";
action = "function() require('dap').continue() end";
lua = true;
desc = "DAP Continue";
}
]
'';
};
colorscheme = mkOption {
description = "Lazy-load on colorscheme.";
type = nullOr (either str (listOf str));
default = null;
};
lazy = mkBool false "Lazy-load manually, e.g. using `trigger_load`.";
priority = mkOption {
type = nullOr int;
description = "Only useful for stat plugins (not lazy-loaded) to force loading certain plugins first.";
default = null;
};
load = mkOption {
type = nullOr lines;
default = null;
description = ''
Lua code to override the `vim.g.lz_n.load()` function for a single plugin.
This will be wrapped in a function.
'';
};
};
};
in {
options.vim.lazy = {
enable = mkEnableOption "plugin lazy-loading via lz.n and lzn-auto-require" // {default = true;};
loader = mkOption {
description = "Lazy loader to use";
type = enum ["lz.n"];
default = "lz.n";
};
plugins = mkOption {
default = [];
type = attrsOf lznPluginType;
description = ''
Plugins to lazy load.
The attribute key is used as the plugin name: for the default `vim.g.lz_n.load`
function this should be either the `package.pname` or `package.name`.
'';
example = ''
{
toggleterm-nvim = {
package = "toggleterm-nvim";
setupModule = "toggleterm";
setupOpts = cfg.setupOpts;
after = "require('toggleterm').do_something()";
cmd = ["ToggleTerm"];
};
$${pkgs.vimPlugins.vim-bbye.pname} = {
package = pkgs.vimPlugins.vim-bbye;
cmd = ["Bdelete" "Bwipeout"];
};
}
'';
};
enableLznAutoRequire = mkOption {
description = ''
Enable lzn-auto-require. Since builtin plugins rely on this, only turn
off for debugging.
'';
type = bool;
default = true;
};
builtLazyConfig = mkOption {
internal = true;
type = lines;
description = ''
The built config for lz.n, or if `vim.lazy.enable` is false, the
individual plugin configs.
'';
};
};
}

View file

@ -5,7 +5,7 @@
}: let }: let
inherit (builtins) map mapAttrs filter; inherit (builtins) map mapAttrs filter;
inherit (lib.attrsets) mapAttrsToList; inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatLines concatMapStringsSep; inherit (lib.strings) concatLines concatMapStringsSep optionalString;
inherit (lib.trivial) showWarnings; inherit (lib.trivial) showWarnings;
inherit (lib.generators) mkLuaInline; inherit (lib.generators) mkLuaInline;
inherit (lib.nvim.dag) entryAfter mkLuarcSection resolveDag entryAnywhere; inherit (lib.nvim.dag) entryAfter mkLuarcSection resolveDag entryAnywhere;
@ -52,7 +52,8 @@ in {
optionsScript = entryAfter ["basic"] (concatLines optionsScript); optionsScript = entryAfter ["basic"] (concatLines optionsScript);
# Basic # Basic
pluginConfigs = entryAfter ["optionsScript"] pluginConfigs; lazyConfigs = entryAfter ["optionsScript"] cfg.lazy.builtLazyConfig;
pluginConfigs = entryAfter ["lazyConfigs"] pluginConfigs;
extraPluginConfigs = entryAfter ["pluginConfigs"] extraPluginConfigs; extraPluginConfigs = entryAfter ["pluginConfigs"] extraPluginConfigs;
mappings = entryAfter ["extraPluginConfigs"] keymaps; mappings = entryAfter ["extraPluginConfigs"] keymaps;
}; };

View file

@ -1,4 +1,4 @@
{ {
"release": "v0.6", "release": "v0.7",
"isReleaseBranch": true "isReleaseBranch": false
} }