Vim: Difference between revisions

From NixOS Wiki
imported>Hhm
add gvim part
imported from old wiki (Remove outdated docs about adding new plugins and point to corresponding section in nixpkgs)
 
(43 intermediate revisions by 30 users not shown)
Line 1: Line 1:
== Using Home Manager ==
<languages/>
<translate>
<!--T:1-->
[https://www.vim.org/ Vim] (vi improved) is a highly configurable modal text editor program for the terminal. 


Vim can easily be set up using [[Home Manager]]. Here's a minimal example:
== Installation == <!--T:2-->
 
=== Basic Install === <!--T:3-->
 
<!--T:73-->
On unstable:
 
</translate>
<syntaxhighlight lang="nix>
  programs.vim.enable = true;
</syntaxhighlight>
<translate>
 
<!--T:74-->
or
 
</translate>
<syntaxhighlight lang="nix>
  programs.vim = {
    enable = true;
    package = pkgs.vim_configurable;
  };
</syntaxhighlight>
<translate>
 
<!--T:75-->
On 24.05 or older:
 
</translate>
<syntaxhighlight lang="nix>
  environment.systemPackages = with pkgs; [ vim ];
</syntaxhighlight>
<translate>
 
<!--T:5-->
or
 
</translate>
<syntaxhighlight lang="nix>
  environment.systemPackages = with pkgs; [ vim_configurable ];
</syntaxhighlight>
<translate>
 
=== Using Home Manager === <!--T:7-->
 
<!--T:8-->
Vim can easily be set up using [[Special:MyLanguage/Home Manager|Home Manager]]. Here's a minimal example:
 
</translate>
<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix>
   programs.vim = {
   programs.vim = {
     enable = true;
     enable = true;
     plugins = [ "vim-airline" ];
     plugins = with pkgs.vimPlugins; [ vim-airline ];
     settings = { ignorecase = true; };
     settings = { ignorecase = true; };
     extraConfig = ''
     extraConfig = ''
Line 12: Line 63:
   };
   };
</syntaxhighlight>
</syntaxhighlight>
<translate>


<!--T:9-->
See [https://github.com/rycee/home-manager/blob/master/modules/programs/vim.nix] for the full set of options.
See [https://github.com/rycee/home-manager/blob/master/modules/programs/vim.nix] for the full set of options.


== Custom setup without using Home Manager ==
=== Vim Spell Files === <!--T:10-->
 
<!--T:11-->
You can configure home-manager to install spelling files into your user directory by packaging individual spell files.  Here' an example for neovim and French:
 
</translate>
<syntaxHighlight lang="nix">
let
nvim-spell-fr-utf8-dictionary = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.utf-8.spl";
  sha256 = "abfb9702b98d887c175ace58f1ab39733dc08d03b674d914f56344ef86e63b61";
};
 
nvim-spell-fr-utf8-suggestions = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.utf-8.sug";
  sha256 = "0294bc32b42c90bbb286a89e23ca3773b7ef50eff1ab523b1513d6a25c6b3f58";
};
 
nvim-spell-fr-latin1-dictionary = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.latin1.spl";
  sha256 = "086ccda0891594c93eab143aa83ffbbd25d013c1b82866bbb48bb1cb788cc2ff";
};
 
nvim-spell-fr-latin1-suggestions = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.latin1.sug";
  sha256 = "5cb2c97901b9ca81bf765532099c0329e2223c139baa764058822debd2e0d22a";
};
in
{
  xdg.configFile."nvim/spell/fr.utf-8.spl".source = nvim-spell-fr-utf8-dictionary;
  xdg.configFile."nvim/spell/fr.utf-8.sug".source = nvim-spell-fr-utf8-suggestions;
  xdg.configFile."nvim/spell/fr.latin1.spl".source = nvim-spell-fr-latin1-dictionary;
  xdg.configFile."nvim/spell/fr.latin1.sug".source = nvim-spell-fr-latin1-suggestions;
}
</syntaxHighlight>
<translate>
 
==== NeoVim with Coc for Python ==== <!--T:16-->
 
<!--T:17-->
For NeoVim use this home manager config:
https://github.com/NixOS/nixpkgs/issues/98166#issuecomment-725319238
 
== System wide vim/nvim configuration == <!--T:18-->
 
<!--T:19-->
If you want a system wide "baseline" configuration for vim/nvim here are two examples:.
 
<!--T:76-->
On unstable:
 
</translate>
<syntaxHighlight lang="nix">
{ pkgs, ... }:
{
  programs.vim = {
    enable = true;
    defaultEditor = true;
    package = (pkgs.vim_configurable.override {  }).customize{
      name = "vim";
<translate>
      <!--T:77-->
# Install plugins for example for syntax highlighting of nix files
</translate>
      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
        start = [ vim-nix vim-lastplace ];
        opt = [];
      };
      vimrcConfig.customRC = ''
<translate>
        <!--T:78-->
" your custom vimrc
</translate>
        set nocompatible
        set backspace=indent,eol,start
<translate>
        <!--T:79-->
" Turn on syntax highlighting by default
</translate>
        syntax on
        " ...
      '';
    };
  };
}
</syntaxHighlight>
<translate>
 
<!--T:80-->
On 24.05 or older:
 
</translate>
<syntaxHighlight lang="nix">
{ pkgs, ... }:
{
  environment.variables = { EDITOR = "vim";
  environment.systemPackages = with pkgs; [
    ((vim_configurable.override {  }).customize{
      name = "vim";
<translate>
      <!--T:81-->
# Install plugins for example for syntax highlighting of nix files
</translate>
      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
        start = [ vim-nix vim-lastplace ];
        opt = [];
      };
      vimrcConfig.customRC = ''
<translate>
        <!--T:82-->
" your custom vimrc
</translate>
        set nocompatible
        set backspace=indent,eol,start
<translate>
        <!--T:83-->
" Turn on syntax highlighting by default
</translate>
        syntax on
        " ...
      '';
    }
  )];
}
</syntaxHighlight>
 
<syntaxHighlight lang="nix">
{ pkgs, ... }:
{
  programs.neovim = {
    enable = true;
    defaultEditor = true;
    vimAlias = true;
    configure = {
      customRC = ''
<translate>
        <!--T:84-->
" your custom vimrc
</translate>
        set nocompatible
        set backspace=indent,eol,start
        " ...
      '';
      packages.myPlugins = with pkgs.vimPlugins; {
        start = [ vim-lastplace vim-nix ];
        opt = [];
      };
    };
  };
}
</syntaxHighlight>
<translate>
 
<!--T:23-->
import these in your <code>configuration.nix</code> and
</translate>
<syntaxHighlight lang="nix">
{   
  imports =   
    [
      ./vim.nix
    ];
  # ...
}
</syntaxHighlight>
<translate>
 
== Custom setup without using Home Manager == <!--T:24-->
 
<!--T:25-->
{{note|To get a general overview about how to set up your vim in nix, refer to [https://www.mpscholten.de/nixos/2016/04/11/setting-up-vim-on-nixos.html mpscholten's blog] }}
{{note|To get a general overview about how to set up your vim in nix, refer to [https://www.mpscholten.de/nixos/2016/04/11/setting-up-vim-on-nixos.html mpscholten's blog] }}
<!--T:26-->
Vim plugins can be installed with the help of nix. You can omit using vim plugin managers and do everything in your <code>.nixpkgs/config</code>.
Vim plugins can be installed with the help of nix. You can omit using vim plugin managers and do everything in your <code>.nixpkgs/config</code>.


A lot of documentation about package management and configuration of vim in nix is stored at [https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vim-plugins/vim-utils.nix vim-utils.nix] in nixpkgs.
<!--T:27-->
A lot of documentation about package management and configuration of vim in nix is stored at [https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/vim-utils.nix] in nixpkgs.


=== Customizations ===
=== Customizations === <!--T:28-->


Both vim and neovim can be further configured to include your favorite plugins and additional libraries. To list all available vim plugins, run <code>nix search nixpkgs.vimPlugins</code>.
<!--T:29-->
Both vim and neovim can be further configured to include your favorite plugins and additional libraries. To list all available vim plugins, run <code>nix search nixpkgs#vimPlugins</code>.


<!--T:30-->
Add the following code to your <code>~/.nixpkgs/config.nix</code>:
Add the following code to your <code>~/.nixpkgs/config.nix</code>:


</translate>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
{
{
Line 32: Line 260:
     myVim = vim_configurable.customize {
     myVim = vim_configurable.customize {
       name = "vim-with-plugins";
       name = "vim-with-plugins";
       # add here code from the example section
<translate>
     }
       <!--T:85-->
# add here code from the example section
</translate>
     };
     myNeovim = neovim.override {
     myNeovim = neovim.override {
       configure = {
       configure = {
         customRC = ''
         customRC = ''
           # here your custom configuration goes!
<translate>
           <!--T:86-->
# here your custom configuration goes!
</translate>
         '';
         '';
         packages.myVimPackage = with pkgs.vimPlugins; {
         packages.myVimPackage = with pkgs.vimPlugins; {
           # see examples below how to use custom packages
<translate>
           <!--T:87-->
# see examples below how to use custom packages
</translate>
           start = [ ];
           start = [ ];
           opt = [ ];
           opt = [ ];
         };    
         };  
     }
      };   
   }
     };
   };
}
}
</syntaxHighlight>
</syntaxHighlight>
<translate>


<!--T:32-->
After that you can install your special grafted `myVim` or `myNeovim` packages.
After that you can install your special grafted `myVim` or `myNeovim` packages.


=== Examples ===
=== Examples === <!--T:33-->
 
==== Apply custom vimrc configuration ==== <!--T:34-->


==== Apply custom vimrc configuration ====
<!--T:35-->
NB: you ''must'' use <code>vimrcConfig.customRC</code> rather than installing a <code>~/.vimrc</code> by hand, since the customized Vim will silently ignore any vimrc in your home directory.


</translate>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
vim_configurable.customize {
vim_configurable.customize {
   name = "vim-with-plugins";
   name = "vim-with-plugins";
   # add custom .vimrc lines like this:
<translate>
   <!--T:88-->
# add custom .vimrc lines like this:
</translate>
   vimrcConfig.customRC = ''
   vimrcConfig.customRC = ''
     set hidden
     set hidden
Line 65: Line 312:
}
}
</syntaxHighlight>
</syntaxHighlight>
<translate>
<!--T:37-->
If you need to run code before plugins are added, you can use <code>vimrcConfig.beforePlugins</code> (be sure to include <code>set nocompatible</code> if you override [https://github.com/NixOS/nixpkgs/blob/c3df8057dad986bf7f3928de1b5233fadb52bb15/pkgs/misc/vim-plugins/vim-utils.nix#L264-L267 the default value]).


=== Using vim's builtin packaging capability ===
=== Using vim's builtin packaging capability === <!--T:38-->


</translate>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
vim_configurable.customize {
vim_configurable.customize {
   vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
   vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
     # loaded on launch
<translate>
     start = [ youcompleteme fugitive ];
     <!--T:89-->
     # manually loadable by calling `:packadd $plugin-name`
# loaded on launch
</translate>
     start = [ YouCompleteMe fugitive ];
<translate>
     <!--T:90-->
# manually loadable by calling `:packadd $plugin-name`
</translate>
     opt = [ phpCompletion elm-vim ];
     opt = [ phpCompletion elm-vim ];
     # To automatically load a plugin when opening a filetype, add vimrc lines like:
<translate>
     <!--T:91-->
# To automatically load a plugin when opening a filetype, add vimrc lines like:
</translate>
     # autocmd FileType php :packadd phpCompletion
     # autocmd FileType php :packadd phpCompletion
   }
   }
};
};
</syntaxHighlight>
</syntaxHighlight>
<translate>
<!--T:40-->
Note that dynamically loading with opt may be buggy and the workaround is to use [https://vi.stackexchange.com/a/20818/30821 start instead].


==== Using VAM as manager ====
=== Using Pathogen as manager === <!--T:41-->
You can add this to you nix configuration to get vim with custom <code>.vimrc</code> and listed plugins.
<syntaxHighlight lang="nix">
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"; }
  ];
};
</syntaxHighlight>
Full documentation at [https://github.com/MarcWeber/vim-addon-manager VAM homepage].


=== Using Pathogen as manager ===
<!--T:42-->
There is a pathogen implementation as well, but its startup is slower and [VAM] has more features.  
There is a pathogen implementation as well, but its startup is slower and [VAM] has more features.  
</translate>
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
vimrcConfig.pathogen.knownPlugins = vimPlugins; # optional
vimrcConfig.pathogen.knownPlugins = vimPlugins; # optional
vimrcConfig.pathogen.pluginNames = [ "vim-addon-nix" "youcompleteme" ];
vimrcConfig.pathogen.pluginNames = [ "vim-addon-nix" "youcompleteme" ];
</syntaxhighlight>
</syntaxhighlight>
<translate>


=== Using Vim-Plug as manager ===
=== Using Vim-Plug as manager === <!--T:43-->


</translate>
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
vimrcConfig.plug.plugins = with pkgs.vimPlugins; [vim-addon-nix youcompleteme];
vimrcConfig.plug.plugins = with pkgs.vimPlugins; [vim-addon-nix youcompleteme];
</syntaxhighlight>
</syntaxhighlight>
<translate>


=== Adding new plugins ===
=== Adding new plugins === <!--T:45-->


* Check https://github.com/NixOS/nixpkgs/tree/master/pkgs/misc/vim-plugins
<!--T:46-->
* Add your plugin to ./vim-plugin-names
Please see https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md.
* Generate via <code>./update.py</code>
* If you need to add additional code/patches to the generated code, add those lines to <code>pkgs/misc/vim-plugins/vim2nix/additional-nix-code</code> and rerun <code>./update.py</code>. They will be included in the generated code.


==== Notes Regarding Plugins ==== <!--T:47-->


=== Add a new custom plugin to the users packages  ===
<!--T:48-->
Sometimes you do not want to change upstream plugins, for this you can use  <code>vimrcConfig.vam.knownPlugins</code> and <code>vimrcConfig.vam.pluginDirectories</code> like this:
For additional info, you may wish to look at [https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md documentation on the nixpkgs repository].


=== Add a new custom plugin to the users packages  === <!--T:49-->
<!--T:50-->
Sometimes you do not want to change upstream plugins, for this you can use  <code>vimUtils.buildVimPlugin</code> to create your own:
</translate>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
let
let
   customPlugins.vim-better-whitespace = pkgs.vimUtils.buildVimPlugin {
   vim-better-whitespace = pkgs.vimUtils.buildVimPlugin {
     name = "vim-better-whitespace";
     name = "vim-better-whitespace";
     src = pkgs.fetchFromGitHub {
     src = pkgs.fetchFromGitHub {
Line 136: Line 393:
     };
     };
   };
   };
in {
in {
  users.users.<yourNickname>.packages = [
  users.users.<yourNickname>.packages = [
     (pkgs.vim_configurable.customize {
     (pkgs.vim_configurable.customize {
      name = "vim";
       vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
       vimrcConfig.vam.knownPlugins = pkgs.vimPlugins // customPlugins;
        start = [ vim-better-whitespace ];
      vimrcConfig.vam.pluginDictionaries = [  
      };
        { names = "vim-better-whitespace" ]; } ]
     })
     })
  ];
};
};
</syntaxHighlight>
</syntaxHighlight>
<translate>


=== Vim as a Python IDE ===
==== Using flake ==== <!--T:53-->


The following snippet will make a full featured python IDE:
</translate>
<code>configuration.nix</code>:
<syntaxHighlight lang="nix">
{ inputs, ... }:
{
  nixpkgs = {
    overlays = [
      (self: super:
        let
          winresizer-vim = super.vimUtils.buildVimPlugin {
            name = "winresizer-vim";
            src = inputs.winresizer-vim;
          };
        in
        {
          vimPlugins =
            super.vimPlugins // {
              inherit winresizer-vim;
            };
        }
      )
    ];
  };
</syntaxHighlight>


<code>flake.nix</code>:
<syntaxHighlight lang="nix">
{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
    winresizer-vim = {
      url = "github:simeji/winresizer";
      flake = false;
    };
  };
  outputs = inputs@{ nixpkgs, ... }: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [
        ./configuration.nix
        ./hardware-configuration.nix
        { nix.registry.nixpkgs.flake = nixpkgs; }
      ];
    };
  };
}
</syntaxHighlight>
<translate>
<!--T:57-->
Then we can update the package with <code>nix flake lock --update-input winresizer-vim</code>, or update all inputs in flake.nix with <code>nix flake update</code>.
=== Vim as a Python IDE === <!--T:58-->
<!--T:59-->
The following snippet will make a full featured python IDE.
==== Using language client ==== <!--T:60-->
</translate>
<syntaxHighlight lang="nix">
<syntaxHighlight lang="nix">
vim_configurable.customize {
vim_configurable.customize {
Line 172: Line 489:
};
};
</syntaxHighlight>
</syntaxHighlight>
<translate>


<!--T:62-->
Then put the following expression in <code>environment.systemPackages</code> or in the home-manager package list,
Then put the following expression in <code>environment.systemPackages</code> or in the home-manager package list,
to install python-language-server:
to install python-language-server:
 
</translate>
<syntaxHighlight  lang="nix">
<syntaxHighlight  lang="nix">
(python3.withPackages(ps: [
(python3.withPackages(ps: [
   ps.python-language-server
   ps.python-language-server
   # the following plugins are optional, they provide type checking, import sorting and code formatting
<translate>
   <!--T:92-->
# the following plugins are optional, they provide type checking, import sorting and code formatting
</translate>
   ps.pyls-mypy ps.pyls-isort ps.pyls-black
   ps.pyls-mypy ps.pyls-isort ps.pyls-black
]))
]))
</syntaxHighlight>
</syntaxHighlight>
<translate>


=== Real life examples ===
=== Real life examples === <!--T:63-->


<!--T:64-->
* [https://github.com/jagajaga/my_configs/blob/master/.nixpkgs/common.nix Jagajaga’s config]
* [https://github.com/jagajaga/my_configs/blob/master/.nixpkgs/common.nix Jagajaga’s config]
<!--T:99-->
* [https://github.com/andrewrk/dotfiles/blob/master/.nixpkgs/config.nix andrewrk's config]
* [https://github.com/andrewrk/dotfiles/blob/master/.nixpkgs/config.nix andrewrk's config]
<!--T:100-->
* [https://github.com/wagnerf42/nixos-config/blob/master/config/my_vim.nix wagnerf42's config (good for rust language)]
* [https://github.com/wagnerf42/nixos-config/blob/master/config/my_vim.nix wagnerf42's config (good for rust language)]


=== YouCompleteMe ===
=== YouCompleteMe === <!--T:65-->
 
<!--T:66-->
Currently the youcompleteme plugin uses [https://github.com/NixOS/nixpkgs/blob/8e7b1f2ac2e261d5a644fef860a0d050ea227c06/pkgs/misc/vim-plugins/default.nix#L695 unwrapped clang on linux]. This causes it to not find <code>stdlib.h</code>. There is a [https://github.com/andrewrk/genesis/blob/5f49cd9a8c2b61b9859a22102bc3f732add9461a/.ycm_extra_conf.py workaround] you can put in your <code>.ycm_extra_conf.py</code> 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 <code>stdlib.h</code>.
Currently the youcompleteme plugin uses [https://github.com/NixOS/nixpkgs/blob/8e7b1f2ac2e261d5a644fef860a0d050ea227c06/pkgs/misc/vim-plugins/default.nix#L695 unwrapped clang on linux]. This causes it to not find <code>stdlib.h</code>. There is a [https://github.com/andrewrk/genesis/blob/5f49cd9a8c2b61b9859a22102bc3f732add9461a/.ycm_extra_conf.py workaround] you can put in your <code>.ycm_extra_conf.py</code> 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 <code>stdlib.h</code>.


<!--T:67-->
A better alternative to youcompleteme for C/C++ is to use [https://github.com/cquery-project/cquery/ cquery] in combination with the [https://github.com/autozimu/LanguageClient-neovim LanguageClient-neovim]. It will also find in c header files when used in a nix-shell if you install cquery from nixpkgs as it uses a custom [https://github.com/NixOS/nixpkgs/commit/04f3b76dcec21f2fcba6b1b0afbb3ed224165050#diff-11cdfc0385b9e017089c1ac09c5b838e shell wrapper]
A better alternative to youcompleteme for C/C++ is to use [https://github.com/cquery-project/cquery/ cquery] in combination with the [https://github.com/autozimu/LanguageClient-neovim LanguageClient-neovim]. It will also find in c header files when used in a nix-shell if you install cquery from nixpkgs as it uses a custom [https://github.com/NixOS/nixpkgs/commit/04f3b76dcec21f2fcba6b1b0afbb3ed224165050#diff-11cdfc0385b9e017089c1ac09c5b838e shell wrapper]


== Python 3 support for vim ==
== Python 3 support for vim == <!--T:68-->


<!--T:69-->
If you have defined your vim configuration in a `./my_vim.nix` file you can install vim with the python 3 support instead of python2 by overriding the python version like the following:
If you have defined your vim configuration in a `./my_vim.nix` file you can install vim with the python 3 support instead of python2 by overriding the python version like the following:
 
</translate>
<syntaxHighlight  lang="nix">
<syntaxHighlight  lang="nix">
(pkgs.callPackage ./my_vim.nix {                                                                                                                                                           
(pkgs.callPackage ./my_vim.nix {                                                                                                                                                           
Line 204: Line 538:
})
})
</syntaxHighlight>
</syntaxHighlight>
<translate>
== gvim and gview == <!--T:70-->


== gvim and gview ==
<!--T:71-->
<code>gvim</code> and <code>gview</code> may be installed using the <code>[https://search.nixos.org/packages/?query=vimHugeX vimHugeX]</code> attribute name (package name <code>[https://search.nixos.org/packages/?query=vim_configurable vim_configurable]</code>).


<code>gvim</code> and <code>gview</code> may be installed using the <code>[https://nixos.org/nixos/packages.html#vimHugeX vimHugeX]</code> attribute name (package name <code>vim_configurable</code>).
</translate>
<syntaxhighlight lang=bash>
<syntaxhighlight lang=bash>
$ nix-env -iA nixos.vimHugeX
$ nix-env -iA nixos.vimHugeX
</syntaxhighlight>
</syntaxhighlight>
<translate>
<!--T:72-->
If you are using <code>vim_configurable.customize</code>, you can enable <code>wrapGui</code> to make <code>gvim</code> available, though this won't give you <code>gview</code>:
</translate>
<syntaxhighlight lang=nix>
vim_configured = pkgs.vim_configurable.customize {
  name = "vim";
  wrapGui = true;
};
</syntaxhighlight>
<translate>
</translate>
[[Category:Applications]]
[[Category:Text Editor{{#translation:}}]]

Latest revision as of 07:24, 4 September 2024

Vim (vi improved) is a highly configurable modal text editor program for the terminal.

Installation

Basic Install

On unstable:

  programs.vim.enable = true;

or

  programs.vim = {
    enable = true;
    package = pkgs.vim_configurable;
  };

On 24.05 or older:

  environment.systemPackages = with pkgs; [ vim ];

or

  environment.systemPackages = with pkgs; [ vim_configurable ];

Using Home Manager

Vim can easily be set up using Home Manager. Here's a minimal example:

  programs.vim = {
    enable = true;
    plugins = with pkgs.vimPlugins; [ vim-airline ];
    settings = { ignorecase = true; };
    extraConfig = ''
      set mouse=a
    '';
  };

See [1] for the full set of options.

Vim Spell Files

You can configure home-manager to install spelling files into your user directory by packaging individual spell files. Here' an example for neovim and French:

let
nvim-spell-fr-utf8-dictionary = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.utf-8.spl";
  sha256 = "abfb9702b98d887c175ace58f1ab39733dc08d03b674d914f56344ef86e63b61";
};

nvim-spell-fr-utf8-suggestions = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.utf-8.sug";
  sha256 = "0294bc32b42c90bbb286a89e23ca3773b7ef50eff1ab523b1513d6a25c6b3f58";
};

nvim-spell-fr-latin1-dictionary = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.latin1.spl";
  sha256 = "086ccda0891594c93eab143aa83ffbbd25d013c1b82866bbb48bb1cb788cc2ff";
};

nvim-spell-fr-latin1-suggestions = builtins.fetchurl {
  url = "http://ftp.vim.org/vim/runtime/spell/fr.latin1.sug";
  sha256 = "5cb2c97901b9ca81bf765532099c0329e2223c139baa764058822debd2e0d22a";
};
in
{
  xdg.configFile."nvim/spell/fr.utf-8.spl".source = nvim-spell-fr-utf8-dictionary;
  xdg.configFile."nvim/spell/fr.utf-8.sug".source = nvim-spell-fr-utf8-suggestions;
  xdg.configFile."nvim/spell/fr.latin1.spl".source = nvim-spell-fr-latin1-dictionary;
  xdg.configFile."nvim/spell/fr.latin1.sug".source = nvim-spell-fr-latin1-suggestions;
}

NeoVim with Coc for Python

For NeoVim use this home manager config: https://github.com/NixOS/nixpkgs/issues/98166#issuecomment-725319238

System wide vim/nvim configuration

If you want a system wide "baseline" configuration for vim/nvim here are two examples:.

On unstable:

{ pkgs, ... }:
{
  programs.vim = {
    enable = true;
    defaultEditor = true;
    package = (pkgs.vim_configurable.override {  }).customize{
      name = "vim";
      # Install plugins for example for syntax highlighting of nix files
      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
        start = [ vim-nix vim-lastplace ];
        opt = [];
      };
      vimrcConfig.customRC = ''
        " your custom vimrc
        set nocompatible
        set backspace=indent,eol,start
        " Turn on syntax highlighting by default
        syntax on
        " ...
      '';
    };
  };
}

On 24.05 or older:

{ pkgs, ... }:
{
  environment.variables = { EDITOR = "vim";
  environment.systemPackages = with pkgs; [
    ((vim_configurable.override {  }).customize{
      name = "vim";
      # Install plugins for example for syntax highlighting of nix files
      vimrcConfig.packages.myplugins = with pkgs.vimPlugins; {
        start = [ vim-nix vim-lastplace ];
        opt = [];
      };
      vimrcConfig.customRC = ''
        " your custom vimrc
        set nocompatible
        set backspace=indent,eol,start
        " Turn on syntax highlighting by default
        syntax on
        " ...
      '';
    }
  )];
}
{ pkgs, ... }:
{
  programs.neovim = {
    enable = true;
    defaultEditor = true;
    vimAlias = true;
    configure = {
      customRC = ''
        " your custom vimrc
        set nocompatible
        set backspace=indent,eol,start
        " ...
      '';
      packages.myPlugins = with pkgs.vimPlugins; {
        start = [ vim-lastplace vim-nix ]; 
        opt = [];
      };
    };
  };
}

import these in your configuration.nix and

{    
  imports =    
    [
      ./vim.nix
    ];
  # ...
}

Custom setup without using Home Manager

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 [2] in nixpkgs.

Customizations

Both vim and neovim can be further configured to include your favorite plugins and additional libraries. To list all available vim plugins, run nix search nixpkgs#vimPlugins.

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

NB: you must use vimrcConfig.customRC rather than installing a ~/.vimrc by hand, since the customized Vim will silently ignore any vimrc in your home directory.

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

If you need to run code before plugins are added, you can use vimrcConfig.beforePlugins (be sure to include set nocompatible if you override the default value).

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
  }
};

Note that dynamically loading with opt may be buggy and the workaround is to use start instead.

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" ];

Using Vim-Plug as manager

vimrcConfig.plug.plugins = with pkgs.vimPlugins; [vim-addon-nix youcompleteme];

Adding new plugins

Please see https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/vim.section.md.

Notes Regarding Plugins

For additional info, you may wish to look at documentation on the nixpkgs repository.

Add a new custom plugin to the users packages

Sometimes you do not want to change upstream plugins, for this you can use vimUtils.buildVimPlugin to create your own:

let
  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 {
      vimrcConfig.packages.myVimPackage = with pkgs.vimPlugins; {
        start = [ vim-better-whitespace ];
      };
    })
  ];
};

Using flake

configuration.nix:

{ inputs, ... }:
{
  nixpkgs = {
    overlays = [
      (self: super:
        let
          winresizer-vim = super.vimUtils.buildVimPlugin {
            name = "winresizer-vim";
            src = inputs.winresizer-vim;
          };
        in
        {
          vimPlugins =
            super.vimPlugins // {
              inherit winresizer-vim;
            };
        }
      )
    ];
  };

flake.nix:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
    winresizer-vim = {
      url = "github:simeji/winresizer";
      flake = false;
    };
  };

  outputs = inputs@{ nixpkgs, ... }: {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [
        ./configuration.nix
        ./hardware-configuration.nix
        { nix.registry.nixpkgs.flake = nixpkgs; }
      ];
    };
  };
}

Then we can update the package with nix flake lock --update-input winresizer-vim, or update all inputs in flake.nix with nix flake update.

Vim as a Python IDE

The following snippet will make a full featured python IDE.

Using language client

vim_configurable.customize {
  vimrcConfig = {
    customRC = ''
      let g:LanguageClient_serverCommands = {
        \ 'python': ['pyls']
        \ }
       nnoremap <F5> :call LanguageClient_contextMenu()<CR>
       nnoremap <silent> gh :call LanguageClient_textDocument_hover()<CR>
       nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>
       nnoremap <silent> gr :call LanguageClient_textDocument_references()<CR>
       nnoremap <silent> gs :call LanguageClient_textDocument_documentSymbol()<CR>
       nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
       nnoremap <silent> gf :call LanguageClient_textDocument_formatting()<CR>
    '';
    packages.myVimPackage = with pkgs.vimPlugins; {
      start = [ LanguageClient-neovim ];
    }
};

Then put the following expression in environment.systemPackages or in the home-manager package list, to install python-language-server:

(python3.withPackages(ps: [
  ps.python-language-server
  # the following plugins are optional, they provide type checking, import sorting and code formatting
  ps.pyls-mypy ps.pyls-isort ps.pyls-black
]))

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.

A better alternative to youcompleteme for C/C++ is to use cquery in combination with the LanguageClient-neovim. It will also find in c header files when used in a nix-shell if you install cquery from nixpkgs as it uses a custom shell wrapper

Python 3 support for vim

If you have defined your vim configuration in a `./my_vim.nix` file you can install vim with the python 3 support instead of python2 by overriding the python version like the following:

(pkgs.callPackage ./my_vim.nix {                                                                                                                                                          
      vim_configurable = vim_configurable.override { python = python3; };                                                                                                                     
})

gvim and gview

gvim and gview may be installed using the vimHugeX attribute name (package name vim_configurable).

$ nix-env -iA nixos.vimHugeX

If you are using vim_configurable.customize, you can enable wrapGui to make gvim available, though this won't give you gview:

vim_configured = pkgs.vim_configurable.customize {
  name = "vim";
  wrapGui = true;
};