1# Vim {#vim} 2 3Both Neovim and Vim can be configured to include your favorite plugins 4and additional libraries. 5 6Loading can be deferred; see examples. 7 8At the moment we support three different methods for managing plugins: 9 10- Vim packages (*recommend*) 11- VAM (=vim-addon-manager) 12- Pathogen 13- vim-plug 14 15## Custom configuration {#custom-configuration} 16 17Adding custom .vimrc lines can be done using the following code: 18 19```nix 20vim_configurable.customize { 21 # `name` specifies the name of the executable and package 22 name = "vim-with-plugins"; 23 24 vimrcConfig.customRC = '' 25 set hidden 26 ''; 27} 28``` 29 30This configuration is used when Vim is invoked with the command specified as name, in this case `vim-with-plugins`. 31 32For Neovim the `configure` argument can be overridden to achieve the same: 33 34```nix 35neovim.override { 36 configure = { 37 customRC = '' 38 # here your custom configuration goes! 39 ''; 40 }; 41} 42``` 43 44If you want to use `neovim-qt` as a graphical editor, you can configure it by overriding Neovim in an overlay 45or passing it an overridden Neovimn: 46 47```nix 48neovim-qt.override { 49 neovim = neovim.override { 50 configure = { 51 customRC = '' 52 # your custom configuration 53 ''; 54 }; 55 }; 56} 57``` 58 59## Managing plugins with Vim packages {#managing-plugins-with-vim-packages} 60 61To store you plugins in Vim packages (the native Vim plugin manager, see `:help packages`) the following example can be used: 62 63```nix 64vim_configurable.customize { 65 vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; { 66 # loaded on launch 67 start = [ youcompleteme fugitive ]; 68 # manually loadable by calling `:packadd $plugin-name` 69 # however, if a Vim plugin has a dependency that is not explicitly listed in 70 # opt that dependency will always be added to start to avoid confusion. 71 opt = [ phpCompletion elm-vim ]; 72 # To automatically load a plugin when opening a filetype, add vimrc lines like: 73 # autocmd FileType php :packadd phpCompletion 74 }; 75} 76``` 77 78`myVimPackage` is an arbitrary name for the generated package. You can choose any name you like. 79For Neovim the syntax is: 80 81```nix 82neovim.override { 83 configure = { 84 customRC = '' 85 # here your custom configuration goes! 86 ''; 87 packages.myVimPackage = with pkgs.vimPlugins; { 88 # see examples below how to use custom packages 89 start = [ ]; 90 # If a Vim plugin has a dependency that is not explicitly listed in 91 # opt that dependency will always be added to start to avoid confusion. 92 opt = [ ]; 93 }; 94 }; 95} 96``` 97 98The resulting package can be added to `packageOverrides` in `~/.nixpkgs/config.nix` to make it installable: 99 100```nix 101{ 102 packageOverrides = pkgs: with pkgs; { 103 myVim = vim_configurable.customize { 104 # `name` specifies the name of the executable and package 105 name = "vim-with-plugins"; 106 # add here code from the example section 107 }; 108 myNeovim = neovim.override { 109 configure = { 110 # add here code from the example section 111 }; 112 }; 113 }; 114} 115``` 116 117After that you can install your special grafted `myVim` or `myNeovim` packages. 118 119### What if your favourite Vim plugin isn’t already packaged? {#what-if-your-favourite-vim-plugin-isnt-already-packaged} 120 121If one of your favourite plugins isn't packaged, you can package it yourself: 122 123```nix 124{ config, pkgs, ... }: 125 126let 127 easygrep = pkgs.vimUtils.buildVimPlugin { 128 name = "vim-easygrep"; 129 src = pkgs.fetchFromGitHub { 130 owner = "dkprice"; 131 repo = "vim-easygrep"; 132 rev = "d0c36a77cc63c22648e792796b1815b44164653a"; 133 sha256 = "0y2p5mz0d5fhg6n68lhfhl8p4mlwkb82q337c22djs4w5zyzggbc"; 134 }; 135 }; 136in 137{ 138 environment.systemPackages = [ 139 ( 140 pkgs.neovim.override { 141 configure = { 142 packages.myPlugins = with pkgs.vimPlugins; { 143 start = [ 144 vim-go # already packaged plugin 145 easygrep # custom package 146 ]; 147 opt = []; 148 }; 149 # ... 150 }; 151 } 152 ) 153 ]; 154} 155``` 156 157### Specificities for some plugins 158#### Tree sitter 159 160By default `nvim-treesitter` encourages you to download, compile and install 161the required tree-sitter grammars at run time with `:TSInstall`. This works 162poorly on NixOS. Instead, to install the `nvim-treesitter` plugins with a set 163of precompiled grammars, you can use `nvim-treesitter.withPlugins` function: 164 165```nix 166(pkgs.neovim.override { 167 configure = { 168 packages.myPlugins = with pkgs.vimPlugins; { 169 start = [ 170 (nvim-treesitter.withPlugins ( 171 plugins: with plugins; [ 172 tree-sitter-nix 173 tree-sitter-python 174 ] 175 )) 176 ]; 177 }; 178 }; 179}) 180``` 181 182To enable all grammars packaged in nixpkgs, use `(pkgs.vimPlugins.nvim-treesitter.withPlugins (plugins: pkgs.tree-sitter.allGrammars))`. 183 184## Managing plugins with vim-plug {#managing-plugins-with-vim-plug} 185 186To use [vim-plug](https://github.com/junegunn/vim-plug) to manage your Vim 187plugins the following example can be used: 188 189```nix 190vim_configurable.customize { 191 vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; { 192 # loaded on launch 193 plug.plugins = [ youcompleteme fugitive phpCompletion elm-vim ]; 194 }; 195} 196``` 197 198For Neovim the syntax is: 199 200```nix 201neovim.override { 202 configure = { 203 customRC = '' 204 # here your custom configuration goes! 205 ''; 206 plug.plugins = with pkgs.vimPlugins; [ 207 vim-go 208 ]; 209 }; 210} 211``` 212 213## Managing plugins with VAM {#managing-plugins-with-vam} 214 215### Handling dependencies of Vim plugins {#handling-dependencies-of-vim-plugins} 216 217VAM introduced .json files supporting dependencies without versioning 218assuming that "using latest version" is ok most of the time. 219 220### Example {#example} 221 222First create a vim-scripts file having one plugin name per line. Example: 223 224```vim 225"tlib" 226{'name': 'vim-addon-sql'} 227{'filetype_regex': '\%(vim)$', 'names': ['reload', 'vim-dev-plugin']} 228``` 229 230Such vim-scripts file can be read by VAM as well like this: 231 232```vim 233call vam#Scripts(expand('~/.vim-scripts'), {}) 234``` 235 236Create a default.nix file: 237 238```nix 239{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }: 240nixpkgs.vim_configurable.customize { name = "vim"; vimrcConfig.vam.pluginDictionaries = [ "vim-addon-vim2nix" ]; } 241``` 242 243Create a generate.vim file: 244 245```vim 246ActivateAddons vim-addon-vim2nix 247let vim_scripts = "vim-scripts" 248call nix#ExportPluginsForNix({ 249\ 'path_to_nixpkgs': eval('{"'.substitute(substitute(substitute($NIX_PATH, ':', ',', 'g'), '=',':', 'g'), '\([:,]\)', '"\1"',"g").'"}')["nixpkgs"], 250\ 'cache_file': '/tmp/vim2nix-cache', 251\ 'try_catch': 0, 252\ 'plugin_dictionaries': ["vim-addon-manager"]+map(readfile(vim_scripts), 'eval(v:val)') 253\ }) 254``` 255 256Then run 257 258```bash 259nix-shell -p vimUtils.vim_with_vim2nix --command "vim -c 'source generate.vim'" 260``` 261 262You should get a Vim buffer with the nix derivations (output1) and vam.pluginDictionaries (output2). 263You can add your Vim to your system's configuration file like this and start it by "vim-my": 264 265```nix 266my-vim = 267 let plugins = let inherit (vimUtils) buildVimPluginFrom2Nix; in { 268 copy paste output1 here 269 }; in vim_configurable.customize { 270 name = "vim-my"; 271 272 vimrcConfig.vam.knownPlugins = plugins; # optional 273 vimrcConfig.vam.pluginDictionaries = [ 274 copy paste output2 here 275 ]; 276 277 # Pathogen would be 278 # vimrcConfig.pathogen.knownPlugins = plugins; # plugins 279 # vimrcConfig.pathogen.pluginNames = ["tlib"]; 280 }; 281``` 282 283Sample output1: 284 285```nix 286"reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation 287 name = "reload"; 288 src = fetchgit { 289 url = "git://github.com/xolox/vim-reload"; 290 rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1"; 291 sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh"; 292 }; 293 dependencies = ["nim-misc"]; 294 295}; 296[...] 297``` 298 299Sample output2: 300 301```nix 302[ 303 ''vim-addon-manager'' 304 ''tlib'' 305 { "name" = ''vim-addon-sql''; } 306 { "filetype_regex" = ''\%(vim)$$''; "names" = [ ''reload'' ''vim-dev-plugin'' ]; } 307] 308``` 309 310## Adding new plugins to nixpkgs {#adding-new-plugins-to-nixpkgs} 311 312Nix expressions for Vim plugins are stored in [pkgs/misc/vim-plugins](/pkgs/misc/vim-plugins). For the vast majority of plugins, Nix expressions are automatically generated by running [`./update.py`](/pkgs/misc/vim-plugins/update.py). This creates a [generated.nix](/pkgs/misc/vim-plugins/generated.nix) file based on the plugins listed in [vim-plugin-names](/pkgs/misc/vim-plugins/vim-plugin-names). Plugins are listed in alphabetical order in `vim-plugin-names` using the format `[github username]/[repository]@[gitref]`. For example https://github.com/scrooloose/nerdtree becomes `scrooloose/nerdtree`. 313 314Some plugins require overrides in order to function properly. Overrides are placed in [overrides.nix](/pkgs/misc/vim-plugins/overrides.nix). Overrides are most often required when a plugin requires some dependencies, or extra steps are required during the build process. For example `deoplete-fish` requires both `deoplete-nvim` and `vim-fish`, and so the following override was added: 315 316```nix 317deoplete-fish = super.deoplete-fish.overrideAttrs(old: { 318 dependencies = with super; [ deoplete-nvim vim-fish ]; 319}); 320``` 321 322Sometimes plugins require an override that must be changed when the plugin is updated. This can cause issues when Vim plugins are auto-updated but the associated override isn't updated. For these plugins, the override should be written so that it specifies all information required to install the plugin, and running `./update.py` doesn't change the derivation for the plugin. Manually updating the override is required to update these types of plugins. An example of such a plugin is `LanguageClient-neovim`. 323 324To add a new plugin, run `./update.py --add "[owner]/[name]"`. **NOTE**: This script automatically commits to your git repository. Be sure to check out a fresh branch before running. 325 326Finally, there are some plugins that are also packaged in nodePackages because they have Javascript-related build steps, such as running webpack. Those plugins are not listed in `vim-plugin-names` or managed by `update.py` at all, and are included separately in `overrides.nix`. Currently, all these plugins are related to the `coc.nvim` ecosystem of Language Server Protocol integration with vim/neovim. 327 328## Updating plugins in nixpkgs {#updating-plugins-in-nixpkgs} 329 330Run the update script with a GitHub API token that has at least `public_repo` access. Running the script without the token is likely to result in rate-limiting (429 errors). For steps on creating an API token, please refer to [GitHub's token documentation](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token). 331 332```sh 333GITHUB_API_TOKEN=my_token ./pkgs/misc/vim-plugins/update.py 334``` 335 336Alternatively, set the number of processes to a lower count to avoid rate-limiting. 337 338```sh 339./pkgs/misc/vim-plugins/update.py --proc 1 340``` 341 342## Important repositories {#important-repositories} 343 344- [vim-pi](https://bitbucket.org/vimcommunity/vim-pi) is a plugin repository 345 from VAM plugin manager meant to be used by others as well used by 346 347- [vim2nix](https://github.com/MarcWeber/vim-addon-vim2nix) which generates the 348 .nix code