<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>neovim &amp;mdash; musicmatzes blog</title>
    <link>https://beyermatthias.de/tag:neovim</link>
    <description></description>
    <pubDate>Mon, 12 Oct 2026 07:16:04 +0200</pubDate>
    <item>
      <title>How to setup (neo)vim on NixOS</title>
      <link>https://beyermatthias.de/how-to-setup-neo-vim-on-nixos</link>
      <description>&lt;![CDATA[This post is about how to setup vim (vimconfigurable) on NixOS with reusable&#xA;parts and the possibility to replace vim with neovim without rewriting the whole&#xA;setup.&#xA;&#xA;!-- more --&#xA;&#xA;configuration.nix&#xA;&#xA;What we have in the configuration.nix file is simple:&#xA;&#xA;environment.systemPackages = let&#xA;    vimPackages = import ./some/directory/vimPackages.nix pkgs;&#xA;    # neovimPackages = import ./some/directory/neovimPackages.nix pkgs;&#xA;in&#xA;    vimPackages ++ with pkgs; [ some other packages ];&#xA;&#xA;You can see that we simply import some nix expressions and pass them the pkgs of&#xA;from our configuration.nix file. Everything else is done in this file and some&#xA;sub-files.&#xA;&#xA;vimPackages.nix&#xA;&#xA;So here starts the fun. We define a function which gets the pkgs variable and&#xA;the lib variable from the outside scope (we don&#39;t pass the lib variable,&#xA;though nix is smart enough to figure out what we mean). We already know that we&#xA;need to return an array of packages, so we can return vim and some things we&#xA;use in our vim scripts, like so:&#xA;&#xA;...&#xA;[ vim pkgs.ctags ]&#xA;&#xA;vim is not prefixed with a pkgs. here because we define it in the file itself.&#xA;But first, we need to know what we want to override. vimcustomize allows us&#xA;to compile vim without GUI support, for example (there are a lot more options).&#xA;We also want to build our vimrc and we want to put plugins into our vim setup,&#xA;because this is the NixOS way of life.&#xA;&#xA;customization = {&#xA;    vimrcConfig = (import ./customization.nix { pkgs = pkgs; });&#xA;} // { name = &#34;vim&#34;; };&#xA;&#xA;Here we import our customization (vimrc, plugins, etc) and ensure that the&#xA;executable is named &#34;vim&#34;. We can now use this customization to customize&#xA;vimconfigurable:&#xA;&#xA;customvim = pkgs.vimconfigurable.customize customization;&#xA;&#xA;and afterwards we override this derivation and set variables, what features&#xA;should be compiled into vim:&#xA;&#xA;vim = lib.overrideDerivation customvim (o: {&#xA;    ftNixSupport = true;&#xA;    gui          = false;&#xA;    luaSupport   = true;&#xA;    # some more&#xA;});&#xA;&#xA;Now we put these parts together and into a function, so the whole file looks&#xA;like this:&#xA;&#xA;{ pkgs, lib, ... }:&#xA;&#xA;let&#xA;  customization = {&#xA;    vimrcConfig = (import ./vim/customization.nix { pkgs = pkgs; });&#xA;  } // { name = &#34;vim&#34;; };&#xA;&#xA;  customvim = pkgs.vimconfigurable.customize customization;&#xA;&#xA;  vim = lib.overrideDerivation customvim (o: {&#xA;    aclSupport              = false;&#xA;    cscopeSupport           = true;&#xA;    darwinSupport           = false;&#xA;    fontsetSupport          = true;&#xA;    ftNixSupport            = true;&#xA;    gpmSupport              = true;&#xA;    gui                     = false;&#xA;    hangulinputSupport      = false;&#xA;    luaSupport              = true;&#xA;    multibyteSupport        = true;&#xA;    mzschemeSupport         = true;&#xA;    netbeansSupport         = false;&#xA;    nlsSupport              = false;&#xA;    perlSupport             = false;&#xA;    pythonSupport           = true;&#xA;    rubySupport             = true;&#xA;    sniffSupport            = false;&#xA;    tclSupport              = false;&#xA;    ximSupport              = false;&#xA;    xsmpSupport             = false;&#xA;    xsmpinteractSupport    = false;&#xA;  });&#xA;&#xA;in [&#xA;  vim&#xA;  pkgs.python&#xA;  pkgs.ctags&#xA;]&#xA;&#xA;But that&#39;s not all to it. The customization.nix is where the real fun&#xA;begins.&#xA;&#xA;customization.nix&#xA;&#xA;So this is the file where we define which plugins we want to use. There are some&#xA;plugins which are not yet included in the nixpkgs repository, so we have to&#xA;build these packages ourselves to be able to install them. Luckily, the nixpkgs&#xA;provide some helper functions to build vim plugin packages rather easily.&#xA;&#xA;Also, we build our vimrc file here, which consists of another bunch of script&#xA;files.&#xA;&#xA;vimrc.nix&#xA;&#xA;The vimrc itself is written in viml of course. If you have a lot of vimrc&#xA;configuration, you can split this file into several smaller ones.&#xA;For example, I have split these files into the following structure:&#xA;&#xA;./&#xA;├── colorschemes&#xA;│   ├── mmnevernessshare.vim&#xA;│   └── razorlight.vim&#xA;├── filetypes.vim&#xA;├── folding.vim&#xA;├── general.vim&#xA;├── gui.vim&#xA;├── insertmode.vim&#xA;├── mappings.vim&#xA;├── menuconf.vim&#xA;├── plugins&#xA;│   ├── # ... some things&#xA;│   └── ycm.vim&#xA;├── pluginconfigurations.nix&#xA;├── scripts.vim&#xA;├── searchnreplace.vim&#xA;├── statusline.vim&#xA;└── textediting.vim&#xA;&#xA;So what we do in our vimrc.nix file (which later gets included in our&#xA;customization.nix file) is: We include all these .vim files and put them&#xA;into one giant string, which is then our vimrc file:&#xA;&#xA;{ stdenv, writeText }:&#xA;&#xA;let&#xA;    generic     = builtins.readFile ./vimrc/general.vim;&#xA;    textediting = builtins.readFile ./vimrc/textediting.vim;&#xA;    # ... more here&#xA;&#xA;    plug = import ./vimrc/pluginconfigurations.nix;&#xA;in&#xA;&#xA;&#39;&#39;&#xA;    ${generic}&#xA;&#xA;    ${textediting}&#xA;&#xA;    # ... more here&#xA;&#xA;    ${plug}&#xA;&#39;&#39;&#xA;&#xA;You might noticed the vimrc/pluginconfigurations.nix file. This one is just&#xA;another layer of abstraction here and is basically the same as the vimrc.nix&#xA;file:&#xA;&#xA;let&#xA;    # some files&#xA;    ycm = builtins.readFile ./plugins/ycm.vim;&#xA;in&#xA;&#xA;&#39;&#39;&#xA;    # some variables&#xA;    ${ycm}&#xA;&#39;&#39;&#xA;&#xA;plugins.nix&#xA;&#xA;Another file we need is the plugins.nix file. As said, not all vim plugins are&#xA;in nixpkgs (yet). So we have to build some vim plugins ourselves (don&#39;t get&#xA;scared here. This does not mean you have to run compilejobs yourself, most&#xA;plugins don&#39;t contain any binaries so rebuilding the system with vim plugins&#xA;installed is normally a matter of seconds).&#xA;&#xA;So this one is also rather simple in the end. In the example below you can see&#xA;how I build the vim-trailing-whitespace plugin. The version might be outdated,&#xA;though.&#xA;&#xA;{ pkgs, fetchgit }:&#xA;&#xA;let&#xA;  buildVimPlugin = pkgs.vimUtils.buildVimPluginFrom2Nix;&#xA;in {&#xA;&#xA;  &#34;vim-trailing-whitespace&#34; = buildVimPlugin {&#xA;    name = &#34;vim-trailing-whitespace&#34;;&#xA;    src = fetchgit {&#xA;      url = &#34;https://github.com/bronson/vim-trailing-whitespace&#34;;&#xA;      rev = &#34;d4ad27de051848e544e360482bdf076b154de0c1&#34;;&#xA;      sha256 = &#34;594769a6f901407609b635a5041966456bfd91b13437169a4562857544e1dca3&#34;;&#xA;    };&#xA;    dependencies = [];&#xA;  };&#xA;&#xA;  # more?&#xA;}&#xA;&#xA;Finally... put the parts together.&#xA;&#xA;Now we can write down our customization.nix file, which imports the&#xA;plugins.nix and vimrc.nix files and puts them in the right context, so the&#xA;nixpkgs infrastructure understands how we want to have our vim package build:&#xA;&#xA;{ pkgs }:&#xA;&#xA;let&#xA;  # this is the vimrc.nix from above&#xA;  vimrc   = pkgs.callPackage ./vimrc.nix {};&#xA;&#xA;  # and the plugins.nix from above&#xA;  plugins = pkgs.callPackage ./plugins.nix {};&#xA;in&#xA;{&#xA;  customRC = vimrc;&#xA;  vam = {&#xA;    knownPlugins = pkgs.vimPlugins // plugins;&#xA;&#xA;    pluginDictionaries = [&#xA;      # from pkgs.vimPlugins&#xA;      { name = &#34;youcompleteme&#34;; }&#xA;&#xA;      # from our own plugin package set&#xA;      { name = &#34;vim-trailing-whitespace&#34;; }&#xA;    ];&#xA;  };&#xA;}&#xA;&#xA;Building&#xA;&#xA;After putting these things together you can rebuild your system. The vim&#xA;binary might be compiled from source, though this isn&#39;t that much of a problem&#xA;because there are only few vim updates, so rebuilding vim will happen every four&#xA;weeks or something, not on every system rebuild.&#xA;&#xA;nixos-rebuild switch&#xA;&#xA;neovim&#xA;&#xA;As said, you can now use the infrastructure we just wrote to compile the very&#xA;same configuration into neovim, including your vimrc, plugins and everything.&#xA;&#xA;{ pkgs, lib, ... }:&#xA;&#xA;let&#xA;  nvim = pkgs.neovim.override {&#xA;    # don&#39;t alias neovim to vim, yet.&#xA;    vimAlias = false;&#xA;&#xA;    configure = (import ./vim/customization.nix { pkgs = pkgs; });&#xA;  };&#xA;&#xA;in [&#xA;  nvim&#xA;  pkgs.python&#xA;  pkgs.ctags&#xA;]&#xA;&#xA;Just make sure your vimrc settings don&#39;t mess with neovim. Some things are not&#xA;supported by neovim, so you have to put them into if-else conditions like so:&#xA;&#xA;if has(&#34;nvim&#34;)&#xA;  &#34; we don&#39;t need this in nvim&#xA;else&#xA;  set clipboard=exclude:.*&#xA;endif&#xA;&#xA;And that&#39;s it.&#xA;tags:  #nix #nixos #vim #neovim #programming&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>This post is about how to setup vim (<code>vim_configurable</code>) on NixOS with reusable
parts and the possibility to replace vim with neovim without rewriting the whole
setup.</p>



<h1 id="configuration-nix" id="configuration-nix">configuration.nix</h1>

<p>What we have in the <code>configuration.nix</code> file is simple:</p>

<pre><code class="language-nix">environment.systemPackages = let
    vimPackages = import ./some/directory/vimPackages.nix pkgs;
    # neovimPackages = import ./some/directory/neovimPackages.nix pkgs;
in
    vimPackages ++ with pkgs; [ some other packages ];
</code></pre>

<p>You can see that we simply import some nix expressions and pass them the pkgs of
from our <code>configuration.nix</code> file. Everything else is done in this file and some
sub-files.</p>

<h1 id="vimpackages-nix" id="vimpackages-nix">vimPackages.nix</h1>

<p>So here starts the fun. We define a function which gets the <code>pkgs</code> variable and
the <code>lib</code> variable from the outside scope (we don&#39;t pass the <code>lib</code> variable,
though nix is smart enough to figure out what we mean). We already know that we
need to return an array of packages, so we can return vim and some things we
use in our vim scripts, like so:</p>

<pre><code># ...
[ vim pkgs.ctags ]
</code></pre>

<p>vim is not prefixed with a <code>pkgs.</code> here because we define it in the file itself.
But first, we need to know what we want to override. <code>vim_customize</code> allows us
to compile vim without GUI support, for example (there are a lot more options).
We also want to build our <code>vimrc</code> and we want to put plugins into our vim setup,
because this is the NixOS way of life.</p>

<pre><code class="language-nix">customization = {
    vimrcConfig = (import ./customization.nix { pkgs = pkgs; });
} // { name = &#34;vim&#34;; };
</code></pre>

<p>Here we import our customization (<code>vimrc</code>, plugins, etc) and ensure that the
executable is named <code>&#34;vim&#34;</code>. We can now use this customization to customize
<code>vim_configurable</code>:</p>

<pre><code class="language-nix">custom_vim = pkgs.vim_configurable.customize customization;
</code></pre>

<p>and afterwards we override this derivation and set variables, what features
should be compiled into vim:</p>

<pre><code class="language-nix">vim = lib.overrideDerivation custom_vim (o: {
    ftNixSupport = true;
    gui          = false;
    luaSupport   = true;
    # some more
});
</code></pre>

<p>Now we put these parts together and into a function, so the whole file looks
like this:</p>

<pre><code class="language-nix">{ pkgs, lib, ... }:

let
  customization = {
    vimrcConfig = (import ./vim/customization.nix { pkgs = pkgs; });
  } // { name = &#34;vim&#34;; };

  custom_vim = pkgs.vim_configurable.customize customization;

  vim = lib.overrideDerivation custom_vim (o: {
    aclSupport              = false;
    cscopeSupport           = true;
    darwinSupport           = false;
    fontsetSupport          = true;
    ftNixSupport            = true;
    gpmSupport              = true;
    gui                     = false;
    hangulinputSupport      = false;
    luaSupport              = true;
    multibyteSupport        = true;
    mzschemeSupport         = true;
    netbeansSupport         = false;
    nlsSupport              = false;
    perlSupport             = false;
    pythonSupport           = true;
    rubySupport             = true;
    sniffSupport            = false;
    tclSupport              = false;
    ximSupport              = false;
    xsmpSupport             = false;
    xsmp_interactSupport    = false;
  });

in [
  vim
  pkgs.python
  pkgs.ctags
]
</code></pre>

<p>But that&#39;s not all to it. The <code>customization.nix</code> is where the <em>real</em> fun
begins.</p>

<h1 id="customization-nix" id="customization-nix">customization.nix</h1>

<p>So this is the file where we define which plugins we want to use. There are some
plugins which are not yet included in the nixpkgs repository, so we have to
build these packages ourselves to be able to install them. Luckily, the nixpkgs
provide some helper functions to build vim plugin packages rather easily.</p>

<p>Also, we build our <code>vimrc</code> file here, which consists of another bunch of script
files.</p>

<h2 id="vimrc-nix" id="vimrc-nix">vimrc.nix</h2>

<p>The <code>vimrc</code> itself is written in <code>viml</code> of course. If you have a lot of <code>vimrc</code>
configuration, you can split this file into several smaller ones.
For example, I have split these files into the following structure:</p>

<pre><code>./
├── colorschemes
│   ├── mm_neverness_share.vim
│   └── razorlight.vim
├── filetypes.vim
├── folding.vim
├── general.vim
├── gui.vim
├── insertmode.vim
├── mappings.vim
├── menuconf.vim
├── plugins
│   ├── # ... some things
│   └── ycm.vim
├── pluginconfigurations.nix
├── scripts.vim
├── searchnreplace.vim
├── statusline.vim
└── textediting.vim
</code></pre>

<p>So what we do in our <code>vimrc.nix</code> file (which later gets included in our
<code>customization.nix</code> file) is: We include all these <code>.vim</code> files and put them
into one giant string, which is then our <code>vimrc</code> file:</p>

<pre><code>{ stdenv, writeText }:

let
    generic     = builtins.readFile ./vimrc/general.vim;
    textediting = builtins.readFile ./vimrc/textediting.vim;
    # ... more here

    plug = import ./vimrc/pluginconfigurations.nix;
in

&#39;&#39;
    ${generic}

    ${textediting}

    # ... more here

    ${plug}
&#39;&#39;
</code></pre>

<p>You might noticed the <code>vimrc/pluginconfigurations.nix</code> file. This one is just
another layer of abstraction here and is basically the same as the <code>vimrc.nix</code>
file:</p>

<pre><code>let
    # some files
    ycm = builtins.readFile ./plugins/ycm.vim;
in

&#39;&#39;
    # some variables
    ${ycm}
&#39;&#39;
</code></pre>

<h2 id="plugins-nix" id="plugins-nix">plugins.nix</h2>

<p>Another file we need is the <code>plugins.nix</code> file. As said, not all vim plugins are
in nixpkgs (yet). So we have to build some vim plugins ourselves (don&#39;t get
scared here. This does not mean you have to run compilejobs yourself, most
plugins don&#39;t contain any binaries so rebuilding the system with vim plugins
installed is normally a matter of seconds).</p>

<p>So this one is also rather simple in the end. In the example below you can see
how I build the <code>vim-trailing-whitespace</code> plugin. The version might be outdated,
though.</p>

<pre><code class="language-nix">{ pkgs, fetchgit }:

let
  buildVimPlugin = pkgs.vimUtils.buildVimPluginFrom2Nix;
in {

  &#34;vim-trailing-whitespace&#34; = buildVimPlugin {
    name = &#34;vim-trailing-whitespace&#34;;
    src = fetchgit {
      url = &#34;https://github.com/bronson/vim-trailing-whitespace&#34;;
      rev = &#34;d4ad27de051848e544e360482bdf076b154de0c1&#34;;
      sha256 = &#34;594769a6f901407609b635a5041966456bfd91b13437169a4562857544e1dca3&#34;;
    };
    dependencies = [];
  };

  # more?
}
</code></pre>

<h2 id="finally-put-the-parts-together" id="finally-put-the-parts-together">Finally... put the parts together.</h2>

<p>Now we can write down our <code>customization.nix</code> file, which imports the
<code>plugins.nix</code> and <code>vimrc.nix</code> files and puts them in the right context, so the
nixpkgs infrastructure understands how we want to have our vim package build:</p>

<pre><code class="language-nix">{ pkgs }:

let
  # this is the vimrc.nix from above
  vimrc   = pkgs.callPackage ./vimrc.nix {};

  # and the plugins.nix from above
  plugins = pkgs.callPackage ./plugins.nix {};
in
{
  customRC = vimrc;
  vam = {
    knownPlugins = pkgs.vimPlugins // plugins;

    pluginDictionaries = [
      # from pkgs.vimPlugins
      { name = &#34;youcompleteme&#34;; }

      # from our own plugin package set
      { name = &#34;vim-trailing-whitespace&#34;; }
    ];
  };
}
</code></pre>

<h1 id="building" id="building">Building</h1>

<p>After putting these things together you can rebuild your system. The <code>vim</code>
binary might be compiled from source, though this isn&#39;t that much of a problem
because there are only few vim updates, so rebuilding vim will happen every four
weeks or something, not on every system rebuild.</p>

<pre><code class="language-bash">nixos-rebuild switch
</code></pre>

<h1 id="neovim" id="neovim">neovim</h1>

<p>As said, you can now use the infrastructure we just wrote to compile the very
same configuration into neovim, including your vimrc, plugins and everything.</p>

<pre><code class="language-nix">{ pkgs, lib, ... }:

let
  nvim = pkgs.neovim.override {
    # don&#39;t alias neovim to vim, yet.
    vimAlias = false;

    configure = (import ./vim/customization.nix { pkgs = pkgs; });
  };

in [
  nvim
  pkgs.python
  pkgs.ctags
]
</code></pre>

<p>Just make sure your <code>vimrc</code> settings don&#39;t mess with neovim. Some things are not
supported by neovim, so you have to put them into <code>if-else</code> conditions like so:</p>

<pre><code class="language-viml">if has(&#34;nvim&#34;)
  &#34; we don&#39;t need this in nvim
else
  set clipboard=exclude:.*
endif
</code></pre>

<p>And that&#39;s it.
tags:  <a href="https://beyermatthias.de/tag:nix" class="hashtag"><span>#</span><span class="p-category">nix</span></a> <a href="https://beyermatthias.de/tag:nixos" class="hashtag"><span>#</span><span class="p-category">nixos</span></a> <a href="https://beyermatthias.de/tag:vim" class="hashtag"><span>#</span><span class="p-category">vim</span></a> <a href="https://beyermatthias.de/tag:neovim" class="hashtag"><span>#</span><span class="p-category">neovim</span></a> <a href="https://beyermatthias.de/tag:programming" class="hashtag"><span>#</span><span class="p-category">programming</span></a></p>
]]></content:encoded>
      <guid>https://beyermatthias.de/how-to-setup-neo-vim-on-nixos</guid>
      <pubDate>Wed, 25 Nov 2015 16:37:43 +0100</pubDate>
    </item>
    <item>
      <title>Contributing to neovim</title>
      <link>https://beyermatthias.de/contributing-to-neovim</link>
      <description>&lt;![CDATA[I&#39;m really happy at the moment. I recently started in contributing to&#xA;neovim.&#xA;&#xA;I&#39;ve done three pull requests by now, one is already closed (without merge,&#xA;though), the other two are still pending but one of them looks really good.&#xA;Just wanted to share...&#xA;&#xA;tags:  #vim #programming #neovim&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>I&#39;m really happy at the moment. I recently started in contributing to
<a href="https://github.com/neovim/neovim">neovim</a>.</p>

<p>I&#39;ve done three pull requests by now, one is already closed (without merge,
though), the other two are still pending but one of them looks really good.
Just wanted to share...</p>

<p>tags:  <a href="https://beyermatthias.de/tag:vim" class="hashtag"><span>#</span><span class="p-category">vim</span></a> <a href="https://beyermatthias.de/tag:programming" class="hashtag"><span>#</span><span class="p-category">programming</span></a> <a href="https://beyermatthias.de/tag:neovim" class="hashtag"><span>#</span><span class="p-category">neovim</span></a></p>
]]></content:encoded>
      <guid>https://beyermatthias.de/contributing-to-neovim</guid>
      <pubDate>Mon, 22 Sep 2014 18:36:19 +0200</pubDate>
    </item>
  </channel>
</rss>