Vim

From NixOS Wiki
Revision as of 05:08, 6 October 2017 by imported>Makefu
Note: To get a general overview about how to set up your vim in nix, refer to mpscholten's blog

Vim plugins can be installed with the help of nix. You can omit using vim plugin managers and do everything in your .nixpkgs/config.

A lot of documentation about package management and configuration of vim in nix is stored at vim-utils.nix in nixpkgs.

Customizations

Both vim and neovim can be further configured to include your favorite plugins and additional libraries.

Add the following code to your ~/.nixpkgs/config.nix:

{
  packageOverrides = pkgs: with pkgs; {
    myVim = vim_configurable.customize {
      name = "vim-with-plugins";
      # add here code from the example section
    }
    myNeovim = neovim.override {
      configure = {
        customRC = ''
          # here your custom configuration goes!
        '';
        packages.myVimPackage = with pkgs.vimPlugins; {
          # see examples below how to use custom packages
          start = [ ];
          opt = [ ];
        };      
    }
  }
}

After that you can install your special grafted `myVim` or `myNeovim` packages.

Examples

Apply custom vimrc configuration

vim_configurable.customize {
  name = "vim-with-plugins";
  # add custom .vimrc lines like this:
  vimrcConfig.customRC = ''
    set hidden
    set colorcolumn=80 
  '';
}

Using vim's builtin packaging capability

vim_configurable.customize {
  vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
    # loaded on launch
    start = [ youcompleteme fugitive ];
    # manually loadable by calling `:packadd $plugin-name`
    opt = [ phpCompletion elm-vim ];
    # To automatically load a plugin when opening a filetype, add vimrc lines like:
    # autocmd FileType php :packadd phpCompletion
  }
};

Using VAM as manager

You can add this to you nix configuration to get vim with custom .vimrc and listed plugins.

vim_configurable.customize {
  name = "vim-with-plugins";
  vimrcConfig.vam.knownPlugins = pkgs.vimPlugins; # optional
  vimrcConfig.vam.pluginDictionaries = [
    # load always
    { name = "youcompleteme"; }
    { names = [ "youcompleteme" "foo" ]; }
    # only load when opening a .php file
    { name = "phpCompletion"; ft_regex = "^php\$"; }
    { name = "phpCompletion"; filename_regex = "^.php\$"; }
    # provide plugin which can be loaded manually:
    { name = "phpCompletion"; tag = "lazy"; }
  ];
};

Full documentation at VAM homepage.

Using Pathogen as manager

There is a pathogen implementation as well, but its startup is slower and [VAM] has more features.

vimrcConfig.pathogen.knownPlugins = vimPlugins; # optional
vimrcConfig.pathogen.pluginNames = [ "vim-addon-nix" "youcompleteme" ];

Adding new plugins

  • Check https://github.com/NixOS/nixpkgs/tree/master/pkgs/misc/vim-plugins
  • Add your plugin to ./vim-plugin-names
  • Generate via nix-shell -p vimPlugins.pluginnames2nix --command "vim-plugin-names-to-nix"
  • If you need to add additional code/patches to the generated code, add those lines to pkgs/misc/vim-plugins/vim2nix/additional-nix-code and rerun vim-plugin-names-to-nix. They will be included in the generated code.


Add a new custom plugin to the users packages

Sometimes you do not want to change upstream plugins, for this you can use vimrcConfig.vam.knownPlugins and vimrcConfig.vam.pluginDirectories like this:

let
  customPlugins.vim-better-whitespace = pkgs.vimUtils.buildVimPlugin {
    name = "vim-better-whitespace";
    src = pkgs.fetchFromGitHub {
      owner = "ntpeters";
      repo = "vim-better-whitespace";
      rev = "984c8da518799a6bfb8214e1acdcfd10f5f1eed7";
      sha256 = "10l01a8xaivz6n01x6hzfx7gd0igd0wcf9ril0sllqzbq7yx2bbk";
    };
  };

in {
   users.users.<yourNickname>.packages = [
    (pkgs.vim_configurable.customize {
      name = "vim";
      vimrcConfig.vam.knownPlugins = pkgs.vimPlugins // customPlugins;
      vimrcConfig.vam.pluginDictionaries = [ 
        { names = "vim-better-whitespace" ]; } ]
    })
};

Real life examples

YouCompleteMe

Currently the youcompleteme plugin uses unwrapped clang on linux. This causes it to not find stdlib.h. There is a workaround you can put in your .ycm_extra_conf.py file, which works by executing the C/C++ compiler and getting it to output the list of search paths - which includes the search path to find stdlib.h.