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```