GithubHelp home page GithubHelp logo

NixNeovim - A Neovim configuration module for NixOS

This flake provides modules for NixOS and Home Manager, which provide the nixneovim configuration options. Using nixneovim, you can configure Neovim, including plugins, through nix. This makes your Neovim config reproducible, and easier to manage.

Forked

This was originally based on pta2002/nixvim. However, today, it shares very little code, approaches problems very differently, and is completely independent.

Get Ready

To use the modules, add this flake to the inputs of your nix configuration.

inputs.nixneovim.url = "github:nixneovim/nixneovim";

Then, apply the overlay and import the modules. This is needed, because NixNeovim uses NixNeovimPlugins to get access to more Neovim plugins.

{
nixpkgs.overlays = [
    nixneovim.overlays.default
];
}

And import the module to your Home Manager (recommended) or NixOS configuration. Depending on your nixos version, you have to import different modules. In particular, the default and homeManager modules only work with the Nixpkgs/HomeManager unstable releases. When you use Nixos/HomeManager XX.XX, please import homeManager-XX-XX or nixos-XX-XX.

For example, when using Home Manager please use:

home-manager = {
  users.<user> = {
    imports = [
      nixneovim.nixosModules.default # with Home Manager unstable
      # nixneovim.nixosModules.homeManager-XX-XX # with Home Manager XX.XX
    ];
    programs.nixneovim.enable = true;.
  };
};

and when you do not use Home Manager please use:

imports = [
    nixneovim.nixosModules.default # with Home Manager unstable
    # nixneovim.nixosModules.homeManager-22-11 # with Home Manager 22.11
    # nixneovim.nixosModules.nixos # without Home Manager
];
}

Documentation

All options are documented at: NixNeovim Documentation. Alternatively, you can use this search: NixNeovim Options Search.

Finally, you can generate the docs using nix build .#docs.

Example Config

Importing the modules gives you access to the programs.nixneovim config. A wiki for all options will be available in the near future.

{
  programs.nixneovim = {
    enable = true;
    extraConfigVim = ''
      # you can add your old config to make the switch easier
      ${lib.strings.fileContents ./init.vim}
      # or with lua
      lua << EOF
        ${lib.strings.fileContents ./init.lua}
      EOF
    '';
    
    # to install plugins just activate their modules
    plugins = {
      lspconfig = {
        enable = true;
        servers = {
          hls.enable = true;
          rust-analyzer.enable = true;
        };
      };
      treesitter = {
        enable = true;
        indent = true;
      };
      mini = {
        enable = true;
        ai.enable = true;
        jump.enable = true;
      };
    };

    # Not all plugins have own modules
    # You can add missing plugins here
    # `pkgs.vimExtraPlugins` is added by the overlay you added at the beginning
    # For a list of available plugins, look here: [available plugins](https://github.com/NixNeovim/NixNeovimPlugins/blob/main/plugins.md)
    extraPlugins = [ pkgs.vimExtraPlugins.<plugin> ];
  };
}

Reduce size of init.lua

Warning: Using this is currently discouraged as it can cause build failures. I am working on it.

By default, NixNeovim prints all config to init.lua in order to have a more stable config. You can turn this off by setting nixneovim.usePluginDefaults. This way, NixNeovim will only print the configs you have changed.

Setting nixneovim.usePluginDefaults to true reduces the size of your init.lua but can lead to unexpected changes of your setup, when a plugin author decides to change their defaults.

Key mappings

You can define your key mappings using the mappings option.

{
  programs.nixneovim = {
    mappings = {
      normalVisualOp = {
        ";" = "':'"; # vimscript between ' '
      };
      normal = {
        "<leader>m" = {
          action = "'<cmd>make<cr>'"; # vimscript between ' '
          silent = true;
        };
        "<leader>h" = "function() print(\"hi\") end"; # Lua code without ' '
      };
    };
  };
}

This uses vim.keymap.set under the hood. Therefore, you can specify lua functions directly. However, this also means, when writing vimscript, you have to put that between extra quotation marks.

This is equivalent to:

vim.keymap.set("", ";", ':')
vim.keymap.set("n", "<leader>m", '<cmd>make<cr>', { silent = true })
vim.keymap.set("n", "<leader>h", function() print("hi") end)

First, you specify the mode; you can choose between the keywords below.

NixNeovim Neovim Description
normalVisualOp "" Normal, visual, select, and operator-pending
normal "n" Normal
insertCommand "!" Insert and command-line
insert "i" Insert
command "c" Command-line
visual "v" Visual and Select
visualOnly "x" Visual
select "s" Select
operator "o" Operator-pending
terminal "t" Terminal
lang "l" Insert, command-line, and lang-arg

When specifying the mapping with an attribute set you can set the following options.

NixNeovim Default VimScript
silent false <silent>
nowait false <silent>
script false <script>
expr false <expr>
unique false <unique>
noremap true Use the 'noremap' variant of the mapping
action Action to execute

Augroups

You can define augroups with the augroups option.

{
  programs.nixneovim = {
    augroups = {
      highlightOnYank = {
        autocmds = [{
          event = "TextYankPost";
          pattern = "*";
          # Or use `vimCallback` with a vimscript function name
          # Or use `command` if you want to run a normal vimscript command
          luaCallback = ''
            vim.highlight.on_yank {
              higroup = (
                vim.fn['hlexists'] 'HighlightedyankRegion' > 0 and 'HighlightedyankRegion' or 'IncSearch'
              ),
              timeout = 200,
            }
          '';
        }];
      };
    };
  };
}

Supported language servers

Until we find a better way of documenting this, you can find a list of supported language servers here: servers.nix

Contribution

Contributions are very welcome. They help improve this project and keep it up to date.

Adding a module

  • Look at the automatically generated issues. Those are plugins available in the original repo, but not yet in this. Start with those, if you like
  • Copy plugin_template.nix or plugin_template_minimal.nix
  • Add the following information:
    • name
    • pluginUrl
    • moduleOptions
    • extraPlugins
  • If not otherwise specified, mkLuaPlugin will add the following string to init.vim:
    • extraConfigLua = "require('${name}').setup ${toLuaObject pluginOptions}";
    • This can be disabled with defaultRequire = false

Adding options to a module

  • When using the plugin_template.nix you add options to the moduleOptions attribute set.
{
  moduleOptions = with helpers; {
    mappings = mkOption {
      type = types.attrs;
      default = { };
    };
    enableAuto = boolOption false "Enable auto expanding snippets";
  };
}
  • In helper/custom_options.nix we have defined several functions for basic plugin options like bool, strings or integer.
  • In particular, ther are:
    • boolOption, intOption, strOption, attrsOption, enumOption

Auto generate module options

⚠️ This is script is under active development and is heavily changed and exented in this PR. Please be careful ⚠️

  • With nix run .#configparser you can convert a Lua setup configs to nix module options (you might need to update the submodule with git submodule update tree-sitter-lua).
  • For example, you can input the following Lua configs (taken from NvimTree; Example-comment added)
nix run .#configparser <<EOF
require("nvim-tree").setup({
  sort_by = "case_sensitive",
  view = {
    -- Example comment
    width = 30,
  },
  renderer = {
    group_empty = true,
  },
  filters = {
    dotfiles = true,
  },
})
EOF
  • The output will be
 {
   sort_by = strOption "case_sensitive" "";
   view = {
     # Example comment
     width = intOption 30 "Example comment";
   };
   renderer = {
     group_empty = boolOption true "";
   };
   filters = {
     dotfiles = boolOption true "";
   };
 }

The output is best-effort and will likely contain errors. For example, the script cannot detect if a variable is a string or an enum. Therefore, you likely have to edit and correct the output before you add it to the module.

Options

{
  programs.nixneovim = {
    options = {
      number = true;         # Show line numbers
      relativenumber = true; # Show relative line numbers

      shiftwidth = 2;        # Tab width should be 2
    };
  };
}

Please note that to, for example, disable numbers you would not set options.nonumber to true, you'd set options.number to false.

Globals

Sometimes you might want to define a global variable, for example to set the leader key. This is easy with the globals attribute:

{
  programs.nixvim = {
    globals.mapleader = ","; # Sets the leader key to comma
  };
}

Support me personally

Buy Me A Coffee

nixneovim's Projects

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.