1# Neovim {#neovim}
2
3Install `neovim-unwrapped` to get a bare-bones Neovim to configure imperatively.
4This is the closest to what you encounter on other distributions.
5
6`neovim` is a wrapper around Neovim with some extra configuration, for
7instance, to set the various language providers like Python.
8The wrapper can be further configured to include your favorite plugins and
9configurations for a reproducible neovim across machines.
10See the next section for more details.
11
12## Custom configuration {#neovim-custom-configuration}
13
14There are two wrappers available to provide additional configuration around the vanilla package `pkgs.neovim-unwrapped`:
151. `wrapNeovim`: the historical one you should use
162. `wrapNeovimUnstable` intended to replace the former. It has more features but
17 the interface is not stable yet.
18
19You can configure the former via:
20
21```nix
22neovim.override {
23 configure = {
24 customRC = ''
25 # here your custom configuration goes!
26 '';
27 packages.myVimPackage = with pkgs.vimPlugins; {
28 # See examples below on how to use custom packages.
29 start = [ ];
30 # If a Vim plugin has a dependency that is not explicitly listed in
31 # `opt`, that dependency will always be added to `start` to avoid confusion.
32 opt = [ ];
33 };
34 };
35}
36```
37`myVimPackage` is an arbitrary name for the generated package. You can choose any name you like.
38
39If you want to use `neovim-qt` as a graphical editor, you can configure it by overriding Neovim in an overlay
40or passing it an overridden Neovim:
41
42```nix
43neovim-qt.override {
44 neovim = neovim.override {
45 configure = {
46 customRC = ''
47 # your custom configuration
48 '';
49 };
50 };
51}
52```
53
54You can use the new unstable wrapper but the interface may change:
55- `autoconfigure`: certain plugins need a custom configuration to work with Nix.
56For instance, `sqlite-lua` needs `g:sqlite_clib_path` to be set to work. Nixpkgs historically patched these in the plugins with several drawbacks: harder maintenance and making upstream work harder. Per convention, these mandatory bits of configuration are bookmarked in nixpkgs in `passthru.initLua`. Enabling `autoconfigure` automatically adds the snippets required for the plugins to work.
57- `autowrapRuntimeDeps`: Appends plugin's runtime dependencies to `PATH`. For instance, `rest.nvim` requires `curl` to work. Enabling `autowrapRuntimeDeps` adds it to the `PATH` visible by your Neovim wrapper (but not your global `PATH`).
58- `luaRcContent`: Extra lua code to add to the generated `init.lua`.
59- `neovimRcContent`: Extra vimL code sourced by the generated `init.lua`.
60- `wrapperArgs`: Extra arguments forwarded to the `makeWrapper` call.
61- `wrapRc`: Nix, not being able to write in your `$HOME`, loads the
62 generated Neovim configuration via the `$VIMINIT` environment variable, i.e. : `export VIMINIT='lua dofile("/nix/store/…-init.lua")'`. This has side effects like preventing Neovim from sourcing your `init.lua` in `$XDG_CONFIG_HOME/nvim` (see bullet 7 of [`:help startup`](https://neovim.io/doc/user/starting.html#startup) in Neovim). Disable it if you want to generate your own wrapper. You can still reuse the generated vimscript init code via `neovim.passthru.initRc`.
63- `plugins`: A list of plugins to add to the wrapper.
64
65```
66wrapNeovimUnstable neovim-unwrapped {
67 autoconfigure = true;
68 autowrapRuntimeDeps = true;
69 luaRcContent = ''
70 vim.o.sessionoptions = 'buffers,curdir,help,tabpages,winsize,winpos,localoptions'
71 vim.g.mapleader = ' '
72 vim.g.maplocalleader = ' '
73 vim.opt.smoothscroll = true
74 vim.opt.colorcolumn = { 100 }
75 vim.opt.termguicolors = true
76 '';
77 # plugins accepts a list of either plugins or { plugin = ...; config = ..vimscript.. };
78 plugins = with vimPlugins; [
79 {
80 plugin = vim-obsession;
81 config = ''
82 map <Leader>$ <Cmd>Obsession<CR>
83 '';
84 }
85 (nvim-treesitter.withPlugins (p: [ p.nix p.python ]))
86 hex-nvim
87 ];
88}
89```
90
91You can explore the configuration with`nix repl` to discover these options and
92override them. For instance:
93```nix
94neovim.overrideAttrs (oldAttrs: {
95 autowrapRuntimeDeps = false;
96})
97```
98
99### Specificities for some plugins {#neovim-plugin-specificities}
100
101### Plugin optional configuration {#neovim-plugin-required-snippet}
102
103Some plugins require specific configuration to work. We choose not to
104patch those plugins but expose the necessary configuration under
105`PLUGIN.passthru.initLua` for neovim plugins. For instance, the `unicode-vim` plugin
106needs the path towards a unicode database so we expose the following snippet `vim.g.Unicode_data_directory="${self.unicode-vim}/autoload/unicode"` under `vimPlugins.unicode-vim.passthru.initLua`.
107
108#### LuaRocks based plugins {#neovim-luarocks-based-plugins}
109
110In order to automatically handle plugin dependencies, several Neovim plugins
111upload their package to [LuaRocks](https://www.luarocks.org). This means less work for nixpkgs maintainers in the long term as dependencies get updated automatically.
112This means several Neovim plugins are first packaged as nixpkgs [lua
113packages](#packaging-a-library-on-luarocks), and converted via `buildNeovimPlugin` in
114a vim plugin. This conversion is necessary because Neovim expects lua folders to be
115top-level while LuaRocks installs them in various subfolders by default.
116
117For instance:
118```nix
119{
120 rtp-nvim = neovimUtils.buildNeovimPlugin { luaAttr = luaPackages.rtp-nvim; };
121}
122```
123To update these packages, you should use the lua updater rather than vim's.
124
125#### Treesitter {#neovim-plugin-treesitter}
126
127By default `nvim-treesitter` encourages you to download, compile and install
128the required Treesitter grammars at run time with `:TSInstall`. This works
129poorly on NixOS. Instead, to install the `nvim-treesitter` plugins with a set
130of precompiled grammars, you can use the `nvim-treesitter.withPlugins` function:
131
132```nix
133(pkgs.neovim.override {
134 configure = {
135 packages.myPlugins = with pkgs.vimPlugins; {
136 start = [
137 (nvim-treesitter.withPlugins (
138 plugins: with plugins; [
139 nix
140 python
141 ]
142 ))
143 ];
144 };
145 };
146})
147```
148
149To enable all grammars packaged in nixpkgs, use `pkgs.vimPlugins.nvim-treesitter.withAllGrammars`.
150
151
152### Testing Neovim plugins {#testing-neovim-plugins}
153
154#### neovimRequireCheck {#testing-neovim-plugins-neovim-require-check}
155`neovimRequireCheck` is a simple test which checks if Neovim can require lua modules without errors. This is often enough to catch missing dependencies.
156
157It accepts a single string for a module, or a list of module strings to test.
158- `nvimRequireCheck = MODULE;`
159- `nvimRequireCheck = [ MODULE1 MODULE2 ];`
160
161When `nvimRequireCheck` is not specified, we will search the plugin's directory for lua modules to attempt loading. This quick smoke test can catch obvious dependency errors that might be missed.
162The check hook will fail the build if any modules cannot be loaded. This encourages inspecting the logs to identify potential issues.
163
164To only check a specific module, add it manually to the plugin definition [overrides](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix).
165
166```nix
167{
168 gitsigns-nvim = super.gitsigns-nvim.overrideAttrs {
169 dependencies = [ self.plenary-nvim ];
170 nvimRequireCheck = "gitsigns";
171 };
172}
173```
174Some plugins will have lua modules that require a user configuration to function properly or can contain optional lua modules that we don't want to test by requiring.
175We can skip specific modules using `nvimSkipModules`. Similar to `nvimRequireCheck`, it accepts a list of strings.
176- `nvimSkipModules = [ MODULE1 MODULE2 ];`
177
178```nix
179{
180 asyncrun-vim = super.asyncrun-vim.overrideAttrs {
181 nvimSkipModules = [
182 # vim plugin with optional toggleterm integration
183 "asyncrun.toggleterm"
184 "asyncrun.toggleterm2"
185 ];
186 };
187}
188```
189
190In rare cases, we might not want to actually test loading lua modules for a plugin. In those cases, we can disable `neovimRequireCheck` with `doCheck = false;`.
191
192This can be manually added through plugin definition overrides in the [overrides.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/overrides.nix).
193```nix
194{
195 vim-test = super.vim-test.overrideAttrs {
196 # Vim plugin with a test lua file
197 doCheck = false;
198 };
199}
200```