mirror of
https://github.com/NotAShelf/neovim-flake.git
synced 2024-11-07 14:55:59 +01:00
422 lines
No EOL
45 KiB
HTML
422 lines
No EOL
45 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>neovim-flake Manual</title><link rel="stylesheet" type="text/css" href="style.css" /><script src="highlight.min.js" type="text/javascript"></script><script src="highlight.load.js" type="text/javascript"></script><meta name="generator" content="DocBook XSL Stylesheets V1.79.2" /><link rel="home" href="index.html" title="neovim-flake Manual" /><link rel="next" href="options.html" title="Appendix A. Configuration Options" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">neovim-flake Manual</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="options.html">Next</a></td></tr></table><hr /></div><div class="book"><div class="titlepage"><div><div><h1 class="title"><a id="book-neovim-flake-manual"></a>neovim-flake Manual</h1></div></div><hr /></div><div class="toc"><dl class="toc"><dt><span class="preface"><a href="index.html#id-1.2">Preface</a></span></dt><dt><span class="chapter"><a href="index.html#ch-try-it-out">1. Try it out</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-using-prebuild-configs">1.1. Using Prebuilt Configs</a></span></dt><dt><span class="section"><a href="index.html#sec-available-configs">1.2. Available Configs</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#_nix">1.2.1. Nix</a></span></dt><dt><span class="section"><a href="index.html#_tidal">1.2.2. Tidal</a></span></dt><dt><span class="section"><a href="index.html#_maximal">1.2.3. Maximal</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="index.html#ch-default-configs">2. Default Configs</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-default-tidal">2.1. Tidal Cycles</a></span></dt><dt><span class="section"><a href="index.html#sec-default-nix">2.2. Nix</a></span></dt><dt><span class="section"><a href="index.html#sec-default-maximal">2.3. Maximal</a></span></dt></dl></dd><dt><span class="chapter"><a href="index.html#ch-custom-configuration">3. Custom Configuration</a></span></dt><dt><span class="chapter"><a href="index.html#ch-custom-package">4. Custom Neovim Package</a></span></dt><dt><span class="chapter"><a href="index.html#ch-custom-plugins">5. Custom Plugins</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-new-method">5.1. New Method</a></span></dt><dt><span class="section"><a href="index.html#sec-old-method">5.2. Old Method</a></span></dt></dl></dd><dt><span class="chapter"><a href="index.html#ch-hm-module">6. Home Manager</a></span></dt><dt><span class="chapter"><a href="index.html#ch-languages">7. Language Support</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#_lsp_custom_packages_command">7.1. LSP Custom Packages/Command</a></span></dt></dl></dd><dt><span class="chapter"><a href="index.html#ch-hacking">8. Hacking neovim-flake</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-contrib-getting-started">8.1. Getting started</a></span></dt><dt><span class="section"><a href="index.html#sec-guidelines">8.2. Guidelines</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-documentation">8.2.1. Add adequate documentation</a></span></dt><dt><span class="section"><a href="index.html#sec-guidelines-code-style">8.2.2. Format your code</a></span></dt><dt><span class="section"><a href="index.html#sec-guidelines-commit-message-style">8.2.3. Format your commit messages</a></span></dt><dt><span class="section"><a href="index.html#sec-commit-style">8.2.4. Commits</a></span></dt><dt><span class="section"><a href="index.html#sec-code-style">8.2.5. Code Style</a></span></dt></dl></dd><dt><span class="section"><a href="index.html#sec-testing">8.3. Testing Your Changes</a></span></dt><dt><span class="section"><a href="index.html#sec-keybinds">8.4. Keybinds</a></span></dt><dd><dl><dt><span class="section"><a href="index.html#sec-custom-key-mappings">8.4.1. Custom Key Mappings Support for a Plugin</a></span></dt></dl></dd><dt><span class="section"><a href="index.html#sec-additional-plugins">8.5. Adding Plugins</a></span></dt></dl></dd><dt><span class="appendix"><a href="options.html">A. Configuration Options</a></span></dt><dt><span class="appendix"><a href="release-notes.html">B. Release Notes</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.1">B.1. Release 0.1</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.1-changelog">B.1.1. Changelog</a></span></dt></dl></dd><dt><span class="section"><a href="release-notes.html#sec-release-0.2">B.2. Release 0.2</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.2-changelog">B.2.1. Changelog</a></span></dt></dl></dd><dt><span class="section"><a href="release-notes.html#sec-release-0.3">B.3. Release 0.3</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.3-changelog">B.3.1. Changelog</a></span></dt></dl></dd><dt><span class="section"><a href="release-notes.html#sec-release-0.4">B.4. Release 0.4</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.4-changelog">B.4.1. Changelog</a></span></dt></dl></dd><dt><span class="section"><a href="release-notes.html#sec-release-0.5">B.5. Release 0.5</a></span></dt><dd><dl><dt><span class="section"><a href="release-notes.html#sec-release-0.5-changelog">B.5.1. Changelog</a></span></dt></dl></dd></dl></dd></dl></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a id="id-1.2"></a>Preface</h1></div></div></div><p>
|
||
If you believe your problem is caused by a bug in neovim-flake then please consider reporting it over
|
||
<a class="link" href="tps://github.com/notashelf/neovim-flake/issues" target="_top">the neovim-flake issue tracker</a>.
|
||
Bugfixes, feature additions and upstream changes are welcome over
|
||
<a class="link" href="https://github.com/notashelf/neovim-flake/pulls" target="_top">the neovim-flake pull requests tab</a>.
|
||
</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-try-it-out"></a>Chapter 1. Try it out</h1></div></div></div><p>Thanks to the portability of Nix, you can try out neovim-flake without actually installing it to your machine.
|
||
Below are the commands you may run to try out different configurations provided by this flake. As of v0.5, three
|
||
configurations are provided:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
Nix
|
||
</li><li class="listitem">
|
||
Tidal
|
||
</li><li class="listitem">
|
||
Maximal
|
||
</li></ul></div><p>You may try out any of the provided configurations using the <code class="literal">nix run</code> command on a system where Nix is installed.</p><pre class="programlisting console">$ cachix use neovim-flake # Optional: it'll save you CPU resources and time
|
||
$ nix run github:notashelf/neovim-flake#nix # will run the default minimal configuration</pre><p>Do keep in mind that this is <span class="strong"><strong>susceptible to garbage collection</strong></span> meaning it will be removed from your Nix store
|
||
once you garbage collect. If you wish to install neovim-flake, please take a look at
|
||
<a class="link" href="index.html#ch-custom-configuration" title="Chapter 3. Custom Configuration">custom-configuration</a> or <a class="link" href="index.html#ch-hm-module" title="Chapter 6. Home Manager">home-manager</a> sections for installation
|
||
instructions.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-using-prebuild-configs"></a>1.1. Using Prebuilt Configs</h2></div></div></div><pre class="programlisting console">$ nix run github:notashelf/neovim-flake#nix
|
||
$ nix run github:notashelf/neovim-flake#tidal
|
||
$ nix run github:notashelf/neovim-flake#maximal</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-available-configs"></a>1.2. Available Configs</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_nix"></a>1.2.1. Nix</h3></div></div></div><p><code class="literal">Nix</code> configuration by default provides LSP/diagnostic support for Nix alongisde a set of visual and functional plugins.
|
||
By running <code class="literal">nix run .</code>, which is the default package, you will build Neovim with this config.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_tidal"></a>1.2.2. Tidal</h3></div></div></div><p>Tidal is an alternative config that adds vim-tidal on top of the plugins from the Nix configuration.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_maximal"></a>1.2.3. Maximal</h3></div></div></div><p><code class="literal">Maximal</code> is the ultimate configuration that will enable support for more commonly used language as well as additional
|
||
complementary plugins. Keep in mind, however, that this will pull a lot of dependencies.</p><p>You are <span class="strong"><strong>strongly</strong></span> recommended to use the binary cache if you would like to try the Maximal configuration.</p></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-default-configs"></a>Chapter 2. Default Configs</h1></div></div></div><p>While you can configure neovim-flake yourself using the builder, here are a few default configurations you can use.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-default-tidal"></a>2.1. Tidal Cycles</h2></div></div></div><pre class="programlisting console">$ nix run github:notashelf/neovim-flake#tidal file.tidal</pre><p>Utilizing <a class="link" href="https://github.com/tidalcycles/vim-tidal" target="_top">vim-tidal</a> and mitchmindtree’s fantastic <a class="link" href="https://github.com/mitchmindtree/tidalcycles.nix" target="_top">tidalcycles.nix</a> start playing with tidal cycles in a single command.</p><p>In your tidal file, type a cycle e.g. <code class="literal">d1 $ s "drum"</code> and then press <span class="emphasis"><em>ctrl+enter</em></span>. Super collider with superdirt, and a modified GHCI with tidal will start up and begin playing. Note, you need jack enabled on your system. If you are using pipewire, its as easy as setting <code class="literal">services.pipewire.jack.enable = true</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-default-nix"></a>2.2. Nix</h2></div></div></div><pre class="programlisting console">$ nix run github:notashelf/neovim-flake#nix test.nix</pre><p>Enables all the of neovim plugins, with language support for specifically Nix. This lets you see what a fully configured neovim setup looks like without downloading a whole bunch of language servers and associated tools.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-default-maximal"></a>2.3. Maximal</h2></div></div></div><pre class="programlisting console">$ nix shell github:notashelf/neovim-flake#maximal test.nix</pre><p>It is the same fully configured neovim as with the <a class="link" href="index.html#sec-default-nix" title="2.2. Nix">Nix</a> config, but with every supported language enabled.</p><div class="note"><h3 class="title">Note</h3><p>Running the maximal config will download <span class="strong"><strong>a lot</strong></span> of packages as it is downloading language servers, formatters, and more.</p></div></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-custom-configuration"></a>Chapter 3. Custom Configuration</h1></div></div></div><p>Custom configuration is done with the <code class="literal">neovimConfiguration</code> while using the flake as a standalone package.
|
||
It takes in the configuration as a module. The output of the configuration function is an attrset.</p><pre class="programlisting nix">{
|
||
options = "The options that were available to configure";
|
||
config = "The outputted configuration";
|
||
pkgs = "The package set used to evaluate the module";
|
||
neovim = "The built neovim package";
|
||
}</pre><p>The following is an example of a barebones vim configuration with the default theme enabled.</p><pre class="programlisting nix">{
|
||
inputs.neovim-flake = {
|
||
url = "github:notashelf/neovim-flake";
|
||
inputs.nixpkgs.follows = "nixpkgs";
|
||
};
|
||
|
||
outputs = {nixpkgs, neovim-flake, ...}: let
|
||
system = "x86_64-linux";
|
||
pkgs = nixpkgs.legacyPackages.${system};
|
||
configModule = {
|
||
# Add any custom options (and feel free to upstream them!)
|
||
# options = ...
|
||
|
||
config.vim = {
|
||
theme.enable = true;
|
||
};
|
||
};
|
||
|
||
customNeovim = neovim-flake.lib.neovimConfiguration {
|
||
modules = [configModule];
|
||
inherit pkgs;
|
||
};
|
||
in {
|
||
# this will make the package available as a flake input
|
||
packages.${system}.neovim = customNeovim.neovim;
|
||
|
||
# this is an example nixosConfiguration using the built neovim package
|
||
nixosConfigurations = {
|
||
yourHostName = nixpkgs.lib.nixosSystem {
|
||
# ...
|
||
modules = [
|
||
./configuration.nix # or whatever your configuration is
|
||
|
||
# this will make wrapped neovim available in your system packages
|
||
{environment.systemPackages = [customNeovim.neovim];}
|
||
];
|
||
# ...
|
||
};
|
||
};
|
||
};
|
||
}</pre><p>Your built neovim configuration can be exposed as a flake output, or be added to your system packages to make
|
||
it available across your system. You may also consider passing the flake output to home-manager to make it available
|
||
to a specific user <span class="strong"><strong>without</strong></span> using the home-manager module.</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-custom-package"></a>Chapter 4. Custom Neovim Package</h1></div></div></div><p>As of v0.5, you may now specify the neovim package that will be wrapped with your configuration. This is done with the <code class="literal">vim.package</code> option.</p><pre class="programlisting nix">{inputs, pkgs, ...}: {
|
||
# using the neovim-nightly overlay
|
||
config.vim.package = inputs.neovim-overlay.packages.${pkgs.system}.neovim;
|
||
}</pre><p>The neovim-nightly-overlay always exposes an unwrapped package. If using a different source, you are highly recommended to get an "unwrapped" version of the neovim package,similar to <code class="literal">neovim-unwrapped</code> in nixpkgs.</p></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-custom-plugins"></a>Chapter 5. Custom Plugins</h1></div></div></div><p>You can use custom plugins, before they are implemented in the flake.
|
||
To add a plugin, you need to add it to your config’s <code class="literal">config.vim.startPlugins</code> array.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-new-method"></a>5.1. New Method</h2></div></div></div><p>As of version 0.5, we have a more extensive API for configuring plugins, under <code class="literal">vim.extraPlugins</code>.</p><p>Instead of using DAGs exposed by the library, you may use the extra plugin module as follows:</p><pre class="programlisting nix">{
|
||
config.vim.extraPlugins = with pkgs.vimPlugins; {
|
||
aerial = {
|
||
package = aerial-nvim;
|
||
setup = ''
|
||
require('aerial').setup {
|
||
-- some lua configuration here
|
||
}
|
||
'';
|
||
};
|
||
|
||
harpoon = {
|
||
package = harpoon;
|
||
setup = "require('harpoon').setup {}";
|
||
after = ["aerial"];
|
||
};
|
||
};
|
||
}</pre></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-old-method"></a>5.2. Old Method</h2></div></div></div><p>Users who have not yet updated to 0.5, or prefer a more hands-on approach may use the old method where the load order
|
||
of the plugins is determined by DAGs.</p><pre class="programlisting nix">{
|
||
# fetch plugin source from GitHub and add it to startPlugins
|
||
config.vim.startPlugins = [
|
||
(pkgs.fetchFromGitHub {
|
||
owner = "FrenzyExists";
|
||
repo = "aquarium-vim";
|
||
rev = "d09b1feda1148797aa5ff0dbca8d8e3256d028d5";
|
||
sha256 = "CtyEhCcGxxok6xFQ09feWpdEBIYHH+GIFVOaNZx10Bs=";
|
||
})
|
||
];
|
||
}</pre><p>However, just making the plugin available might not be enough. In that case, you can write custom vimscript
|
||
or lua config, using <code class="literal">config.vim.configRC</code> or <code class="literal">config.vim.luaConfigRC</code> respectively.
|
||
These options are attribute sets, and you need to give the configuration you’re adding some name, like this:</p><pre class="programlisting nix">{
|
||
# this will create an "aquarium" section in your init.vim with the contents of your custom config
|
||
# which will be *appended* to the rest of your configuration, inside your init.vim
|
||
config.vim.configRC.aquarium = "colorscheme aquiarum";
|
||
}</pre><p>Note: If your configuration needs to be put in a specific place in the config, you can use functions from
|
||
<code class="literal">inputs.neovim-flake.lib.nvim.dag</code> to order it.
|
||
Refer to <a class="link" href="https://github.com/nix-community/home-manager/blob/master/modules/lib/dag.nix" target="_top">https://github.com/nix-community/home-manager/blob/master/modules/lib/dag.nix</a> to find out more about
|
||
the DAG system.</p><p>Also, if you successfully made your plugin work, please make a PR to add it to the flake, or open an issue
|
||
with your findings so that we can make it available for everyone easily.</p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-hm-module"></a>Chapter 6. Home Manager</h1></div></div></div><p>The Home Manager module allows us to customize the different <code class="literal">vim</code> options from inside the home-manager configuration
|
||
and it is the preferred way of configuring neovim-flake, both on NixOS and non-NixOS systems.</p><p>To use it, we first add the input flake.</p><pre class="programlisting nix">{
|
||
neovim-flake = {
|
||
url = github:notashelf/neovim-flake;
|
||
# you can override input nixpkgs
|
||
inputs.nixpkgs.follows = "nixpkgs";
|
||
# you can also override individual plugins
|
||
# i.e inputs.obsidian-nvim.follows = "obsidian-nvim"; # <- obsidian nvim needs to be in your inputs
|
||
};
|
||
}</pre><p>Followed by importing the home-manager module somewhere in your configuration.</p><pre class="programlisting nix">{
|
||
# assuming neovim-flake is in your inputs and inputs is in the argset
|
||
imports = [ inputs.neovim-flake.homeManagerModules.default ];
|
||
}</pre><p>An example installation for standalone home-manager would look like this:</p><pre class="programlisting nix">{
|
||
inputs = {
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||
home-manager.url = "github:nix-community/home-manager";
|
||
stylix.url = "github:notashelf/neovim-flake";
|
||
};
|
||
|
||
outputs = { nixpkgs, home-manager, neovim-flake ... }: let
|
||
system = "x86_64-linux"; in {
|
||
# ↓ this is the home-manager output in the flake schema
|
||
homeConfigurations."yourUsername»" = home-manager.lib.homeManagerConfiguration {
|
||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
||
modules = [
|
||
neovim-flake.homeManagerModules.default # <- this imports the home-manager module that provides the options
|
||
./home.nix # your home-manager configuration, probably where you will want to add programs.neovim-flake options
|
||
];
|
||
};
|
||
};
|
||
}</pre><p>Once the module is imported, we will be able to define the following options (and much more) from inside the
|
||
home-manager configuration.</p><pre class="programlisting nix">{
|
||
programs.neovim-flake = {
|
||
|
||
enable = true;
|
||
# your settings need to go into the settings attribute set
|
||
# most settings are documented in the appendix
|
||
settings = {
|
||
vim.viAlias = false;
|
||
vim.vimAlias = true;
|
||
vim.lsp = {
|
||
enable = true;
|
||
};
|
||
};
|
||
};
|
||
}</pre><div class="note"><h3 class="title">Note</h3><p>You may find all avaliable options in the <a class="link" href="https://notashelf.github.io/neovim-flake/options" target="_top">appendix</a></p></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-languages"></a>Chapter 7. Language Support</h1></div></div></div><p>Language specific support means there is a combination of language specific plugins, <code class="literal">treesitter</code> support, <code class="literal">nvim-lspconfig</code> language servers, and <code class="literal">null-ls</code> integration. This gets you capabilities ranging from autocompletion to formatting to diagnostics. The following languages have sections under the <code class="literal">vim.languages</code> attribute. See the configuration docs for details.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
Rust: <a class="xref" href="options.html#opt-vim.languages.rust.enable"><code class="option">vim.languages.rust.enable</code></a>
|
||
</li><li class="listitem">
|
||
Nix: <a class="xref" href="options.html#opt-vim.languages.nix.enable"><code class="option">vim.languages.nix.enable</code></a>
|
||
</li><li class="listitem">
|
||
SQL: <a class="xref" href="options.html#opt-vim.languages.sql.enable"><code class="option">vim.languages.sql.enable</code></a>
|
||
</li><li class="listitem">
|
||
C/C++: <a class="xref" href="options.html#opt-vim.languages.clang.enable"><code class="option">vim.languages.clang.enable</code></a>
|
||
</li><li class="listitem">
|
||
Typescript/Javascript: <a class="xref" href="options.html#opt-vim.languages.ts.enable"><code class="option">vim.languages.ts.enable</code></a>
|
||
</li><li class="listitem">
|
||
Python: <a class="xref" href="options.html#opt-vim.languages.python.enable"><code class="option">vim.languages.python.enable</code></a>:
|
||
</li><li class="listitem">
|
||
Zig: <a class="xref" href="options.html#opt-vim.languages.zig.enable"><code class="option">vim.languages.zig.enable</code></a>
|
||
</li><li class="listitem">
|
||
Markdown: <a class="xref" href="options.html#opt-vim.languages.markdown.enable"><code class="option">vim.languages.markdown.enable</code></a>
|
||
</li><li class="listitem">
|
||
HTML: <a class="xref" href="options.html#opt-vim.languages.html.enable"><code class="option">vim.languages.html.enable</code></a>
|
||
</li><li class="listitem">
|
||
SQL: <a class="xref" href="options.html#opt-vim.languages.sql.enable"><code class="option">vim.languages.sql.enable</code></a>
|
||
</li><li class="listitem">
|
||
Dart: <a class="xref" href="options.html#opt-vim.languages.dart.enable"><code class="option">vim.languages.dart.enable</code></a>
|
||
</li><li class="listitem">
|
||
Go: <a class="xref" href="options.html#opt-vim.languages.go.enable"><code class="option">vim.languages.go.enable</code></a>
|
||
</li><li class="listitem">
|
||
Lua: <a class="xref" href="options.html#opt-vim.languages.lua.enable"><code class="option">vim.languages.lua.enable</code></a>
|
||
</li><li class="listitem">
|
||
PHP: <a class="xref" href="options.html#opt-vim.languages.php.enable"><code class="option">vim.languages.php.enable</code></a>
|
||
</li></ul></div><p>Adding support for more languages, and improving support for existing ones are great places
|
||
where you can contribute with a PR.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_lsp_custom_packages_command"></a>7.1. LSP Custom Packages/Command</h2></div></div></div><p>In any of the <code class="literal">opt.languages.<language>.lsp.package</code> options you can provide your own LSP package, or provide
|
||
the command to launch the language server, as a list of strings.</p><p>You can use this to skip automatic installation of a language server, and instead
|
||
use the one found in your <code class="literal">$PATH</code> during runtime, for example:</p><pre class="programlisting nix">vim.languages.java = {
|
||
lsp = {
|
||
enable = true;
|
||
package = ["jdt-language-server" "-data" "~/.cache/jdtls/workspace"];
|
||
};
|
||
}</pre></div></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a id="ch-hacking"></a>Chapter 8. Hacking neovim-flake</h1></div></div></div><p>neovim-flake is designed for developers as much as it is for the end user. I would like any potential contributor
|
||
to be able to propagate their desired changes into the repository without the extra effort. As such, below are guides
|
||
(and guidelines) to streamline the contribution process and ensure that your valuable input seamlessly integrates
|
||
into neovim-flake’s development without leaving question marks in your head.</p><p>This section is mainly directed towards those who wish to contribute code into neovim-flake. If you wish to instead
|
||
report a bug or discuss a potential feature implementation, first look among the already <a class="link" href="https://github.com/notashelf/neovim-flake/issues" target="_top">open issues</a> and
|
||
if no matching issue exists you may open a <a class="link" href="https://github.com/notashelf/neovim-flake/issues/new" target="_top">new issue</a> and describe your problem/request. While creating an
|
||
issue, please try to include as much information as you can, ideally also include relevant context in which an issue
|
||
occurs or a feature should be implemented.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-contrib-getting-started"></a>8.1. Getting started</h2></div></div></div><p>You naturally would like to start by forking the repository. If you are new to git, have a look at GitHub’s
|
||
<a class="link" href="https://help.github.com/articles/fork-a-repo/" target="_top">Fork a repo guide</a> for instructions on how you can do this. Once you have a fork of neovim-flake
|
||
you should create a branch starting at the most recent <code class="literal">main</code> branch.
|
||
Give your branch a reasonably descriptive name, suffixed by its type - i.e <code class="literal">feature/debugger</code> or <code class="literal">fix/pesky-bug</code>.</p><p>Implement your changes and commit them to the newly created branch and when you are happy with the result and positive
|
||
that it fulfills <a class="xref" href="index.html#sec-guidelines" title="8.2. Guidelines">Section 8.2, “Guidelines”</a>. Once you are confident everything is in order, push the branch to GitHub and</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-guidelines"></a>8.2. Guidelines</h2></div></div></div><p>If your contribution tightly follows the guidelines, then there is a good chance it will be merged without too much
|
||
trouble. Some of the guidelines will be strictly enforced, others will remain as gentle nudges towards the correct
|
||
direction. As we have no automated system enforcing those guidelines, please try to double check your changes before
|
||
making your pull request in order to avoid "faulty" code slipping by.</p><p>If you are uncertain how these rules affect the change you would like to make then feel free to start a
|
||
discussion in the <a class="link" href="https://github.com/NotAShelf/neovim-flake/discussions" target="_top">discussions tab</a> ideally (but not necessarily) before you start developing.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-documentation"></a>8.2.1. Add adequate documentation</h3></div></div></div><p>Most, if not all, changes warrant changes to the documentation. Module options should be documented with
|
||
<a class="link" href="https://nixos.org/manual/nixpkgs/unstable/#sec-contributing-markup" target="_top">Nixpkgs-flavoured Markdown</a>, albeit with exceptions.
|
||
neovim-flake is itself documented using a combination of <a class="link" href="https://tdg.docbook.org/" target="_top">DocBook</a> and <a class="link" href="https://asciidoc.org/" target="_top">AsciiDoc</a> conventions.</p><p>The HTML version of this manual containing both the module option descriptions and the documentation of neovim-flake
|
||
(such as this page) can be generated and opened by typing the following in a shell within a clone of the
|
||
neovim-flake Git repository:</p><pre class="programlisting console">$ nix build .#docs-html
|
||
$ xdg-open ./result/share/doc/neovim-flake/index.html</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-guidelines-code-style"></a>8.2.2. Format your code</h3></div></div></div><p>Make sure your code is formatted as described in <a class="xref" href="index.html#sec-code-style" title="8.2.5. Code Style">Section 8.2.5, “Code Style”</a>. To maintain consistency throughout the project
|
||
you are encouraged to browse through existing code and adopt its style also in new code.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-guidelines-commit-message-style"></a>8.2.3. Format your commit messages</h3></div></div></div><p>Similar to <a class="xref" href="index.html#sec-guidelines-code-style" title="8.2.2. Format your code">Section 8.2.2, “Format your code”</a> we encourage a consistent commit message format as described
|
||
in <a class="xref" href="index.html#sec-commit-style" title="8.2.4. Commits">Section 8.2.4, “Commits”</a>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-commit-style"></a>8.2.4. Commits</h3></div></div></div><p>The commits in your pull request should be reasonably self-contained. Which means each and every commit in
|
||
a pull request should make sense both on its own and in general context. That is, a second commit should not resolve
|
||
an issue that is introduced in an earlier commit. In particular, you will be asked to amend any commit that
|
||
introduces syntax errors or similar problems even if they are fixed in a later commit.</p><p>The commit messages should follow the <a class="link" href="https://cbea.ms/git-commit/#seven-rules" target="_top">seven rules</a>, except for "Capitalize the subject line".
|
||
We also ask you to include the affected code component or module in the first line.
|
||
A commit message ideally, but not necessarily, follow the given template from home-manager’s own documentation</p><pre class="screen">{component}: {description}
|
||
|
||
{long description}</pre><p>where <code class="literal">{component}</code> refers to the code component (or module) your change affects, <code class="literal">{description}</code> is a very brief
|
||
description of your change, and <code class="literal">{long description}</code> is an optional clarifying description. As a rare exception, if
|
||
there is no clear component, or your change affects many components, then the <code class="literal">{component}</code> part is optional.
|
||
See <a class="xref" href="index.html#ex-commit-message" title="Example 8.1. Compliant commit message">Example 8.1, “Compliant commit message”</a> for a commit message that fulfills these requirements.</p><div class="example"><a id="ex-commit-message"></a><p class="title"><strong>Example 8.1. Compliant commit message</strong></p><div class="example-contents"><p>The commit <a class="link" href="https://github.com/nix-community/home-manager/commit/69f8e47e9e74c8d3d060ca22e18246b7f7d988ef" target="_top">69f8e47e9e74c8d3d060ca22e18246b7f7d988ef</a> contains the commit message</p><pre class="screen">starship: allow running in Emacs if vterm is used
|
||
|
||
The vterm buffer is backed by libvterm and can handle Starship prompts
|
||
without issues.</pre></div></div><br class="example-break" /><p>Long description can be ommitted if the change is too simple to warrant it. A minor fix in spelling or a formatting
|
||
change does not warrant long description, however, a module addition or removal does as you would like to provide the
|
||
relevant context for your changes.</p><p>Finally, when adding a new module, say <code class="literal">modules/foo.nix</code>, we use the fixed commit format <code class="literal">foo: add module</code>.
|
||
You can, of course, still include a long description if you wish.</p><p>In case of nested modules, i.e <code class="literal">modules/languages/java.nix</code> you are recommended to contain the parent as well - for
|
||
example <code class="literal">languages/java: some major change</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-code-style"></a>8.2.5. Code Style</h3></div></div></div><p><span class="strong"><strong>Treewide</strong></span>
|
||
Keep lines at a reasonable width, ideally 80 characters or less. This also applies to string literals and module
|
||
descriptions and documentation.</p><p><span class="strong"><strong>Nix</strong></span>
|
||
neovim-flake is formatted by the <a class="link" href="https://github.com/kamadorueda/alejandra" target="_top">alejandra</a> tool and the formatting is checked in the pull
|
||
request and push workflows. Run the <code class="literal">nix fmt</code> command inside the project repository before submitting your
|
||
pull request.</p><p>While Alejandra is mostly opinionated on how code looks after formatting, certain changes are done at the
|
||
user’s discretion based on how the original code was structured.</p><p>Please use one line code for attribute sets that contain only one subset.
|
||
For example:</p><pre class="programlisting nix"># parent modules should always be unfolded
|
||
module = {
|
||
value = mkEnableOption "some description" // { default = true; }; # merges can be done inline where possible
|
||
|
||
# same as parent modules, unfold submodules
|
||
subModule = {
|
||
# this is an option that contains more than one nested value
|
||
someOtherValue = mkOption {
|
||
type = lib.types.bool;
|
||
description = "Some other description"
|
||
default = true;
|
||
};
|
||
};
|
||
}</pre><p>If you move a line down after the merge operator, Alejandra will automatically unfold the whole merged attrset
|
||
for you, which we <span class="strong"><strong>do not</strong></span> want.</p><pre class="programlisting nix">module = {
|
||
key = mkEnableOption "some description" // {
|
||
default = true; # we want this to be inline
|
||
};
|
||
# ...
|
||
}</pre><p>For lists, it is mostly up to your own discretion how you want to format them, but please try to unfold lists if
|
||
they contain multiple items and especially if they are to include comments.</p><pre class="programlisting nix"># this is ok
|
||
acceptableList = [
|
||
item1 # comment
|
||
item2
|
||
item3 # some other comment
|
||
item4
|
||
];
|
||
|
||
# this is not ok
|
||
listToBeAvoided = [item1 item2 /* comment */ item3 item4];
|
||
|
||
# this is ok
|
||
singleItemList = [item1];</pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-testing"></a>8.3. Testing Your Changes</h2></div></div></div><p>Once you have made your changes, you will need to test them throughly. If it is a module, add your module option to
|
||
<code class="literal">configuration.nix</code> (located in the root of this project) inside <code class="literal">neovimConfiguration</code>. Enable it, and then run the
|
||
maximal configuration with <code class="literal">nix run .#maximal -Lv</code> to check for build errors. If neovim opens in the current directory
|
||
without any error messages (you can check the output of <code class="literal">:messages</code> inside neovim to see if there are any errors), then
|
||
your changes are good to go. Open your pull request, and it will be reviewed as soon as posssible.</p><p>If it is not a new module, but a change to an existing one, then make sure the module you have changed is enabled in the
|
||
maximal configuration by editing configuration.nix, and then run it with <code class="literal">nix run .#maximal -Lv</code>. Same procedure as
|
||
adding a new module will apply here.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-keybinds"></a>8.4. Keybinds</h2></div></div></div><p>As of 0.4, there exists an API for writing your own keybinds and a couple of useful utility functions are available in
|
||
the <a class="link" href="https://github.com/NotAShelf/neovim-flake/tree/main/lib" target="_top">extended standard library</a>. The following section contains
|
||
a general overview to how you may utilize said functions.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="sec-custom-key-mappings"></a>8.4.1. Custom Key Mappings Support for a Plugin</h3></div></div></div><p>To set a mapping, you should define it in <code class="literal">vim.maps.<<mode>></code>.
|
||
The available modes are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
normal
|
||
</li><li class="listitem">
|
||
insert
|
||
</li><li class="listitem">
|
||
select
|
||
</li><li class="listitem">
|
||
visual
|
||
</li><li class="listitem">
|
||
terminal
|
||
</li><li class="listitem">
|
||
normalVisualOp
|
||
</li><li class="listitem">
|
||
visualOnly
|
||
</li><li class="listitem">
|
||
operator
|
||
</li><li class="listitem">
|
||
insertCommand
|
||
</li><li class="listitem">
|
||
lang
|
||
</li><li class="listitem">
|
||
command
|
||
</li></ul></div><p>An example, simple keybinding, can look like this:</p><pre class="programlisting nix">{
|
||
vim.maps.normal = {
|
||
"<leader>wq" = {
|
||
action = ":wq<CR>";
|
||
silent = true;
|
||
desc = "Save file and quit";
|
||
};
|
||
};
|
||
}</pre><p>There are many settings available in the options. Please refer to the <a class="link" href="https://notashelf.github.io/neovim-flake/options.html#opt-vim.maps.command._name_.action" target="_top">documentation</a> to see a list of them.</p><p><code class="literal">neovim-flake</code> provides a list of helper commands, so that you don’t have to write the mapping attribute sets every
|
||
time:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="literal">mkBinding = key: action: desc:</code> - makes a basic binding, with <code class="literal">silent</code> set to true.
|
||
</li><li class="listitem">
|
||
<code class="literal">mkExprBinding = key: action: desc:</code> - makes an expression binding, with <code class="literal">lua</code>, <code class="literal">silent</code>, and <code class="literal">expr</code> set to true.
|
||
</li><li class="listitem">
|
||
<code class="literal">mkLuaBinding = key: action: desc:</code> - makes an expression binding, with <code class="literal">lua</code>, and <code class="literal">silent</code> set to true.
|
||
</li></ul></div><p>Note that the Lua in these bindings is actual Lua, not pasted into a <code class="literal">:lua</code> command.
|
||
Therefore, you either pass in a function like <code class="literal">require('someplugin').some_function</code>, without actually calling it,
|
||
or you define your own function, like <code class="literal">function() require('someplugin').some_function() end</code>.</p><p>Additionally, to not have to repeat the descriptions, there’s another utility function with its own set of functions:</p><pre class="programlisting nix"># Utility function that takes two attrsets:
|
||
# { someKey = "some_value" } and
|
||
# { someKey = { description = "Some Description"; }; }
|
||
# and merges them into
|
||
# { someKey = { value = "some_value"; description = "Some Description"; }; }
|
||
|
||
addDescriptionsToMappings = actualMappings: mappingDefinitions:</pre><p>This function can be used in combination with the same <code class="literal">mkBinding</code> functions as above, except they only take two
|
||
arguments - <code class="literal">binding</code> and <code class="literal">action</code>, and have different names:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<code class="literal">mkSetBinding = binding: action:</code> - makes a basic binding, with <code class="literal">silent</code> set to true.
|
||
</li><li class="listitem">
|
||
<code class="literal">mkSetExprBinding = binding: action:</code> - makes an expression binding, with <code class="literal">lua</code>, <code class="literal">silent</code>, and <code class="literal">expr</code> set to true.
|
||
</li><li class="listitem">
|
||
<code class="literal">mkSetLuaBinding = binding: action:</code> - makes an expression binding, with <code class="literal">lua</code>, and <code class="literal">silent</code> set to true.
|
||
</li></ul></div><p>You can read the source code of some modules to see them in action, but their usage should look something like this:</p><pre class="programlisting nix"># plugindefinition.nix
|
||
{lib, ...}:
|
||
with lib; {
|
||
options.vim.plugin = {
|
||
enable = mkEnableOption "Enable plugin";
|
||
|
||
# Mappings should always be inside an attrset called mappings
|
||
mappings = {
|
||
# mkMappingOption is a helper function from lib,
|
||
# that takes a description (which will also appear in which-key),
|
||
# and a default mapping (which can be null)
|
||
toggleCurrentLine = mkMappingOption "Toggle current line comment" "gcc";
|
||
toggleCurrentBlock = mkMappingOption "Toggle current block comment" "gbc";
|
||
|
||
toggleOpLeaderLine = mkMappingOption "Toggle line comment" "gc";
|
||
toggleOpLeaderBlock = mkMappingOption "Toggle block comment" "gb";
|
||
|
||
toggleSelectedLine = mkMappingOption "Toggle selected comment" "gc";
|
||
toggleSelectedBlock = mkMappingOption "Toggle selected block" "gb";
|
||
};
|
||
};
|
||
}</pre><pre class="programlisting nix"># config.nix
|
||
{
|
||
pkgs,
|
||
config,
|
||
lib,
|
||
...
|
||
}:
|
||
with lib;
|
||
with builtins; let
|
||
cfg = config.vim.plugin;
|
||
self = import ./plugindefinition.nix {inherit lib;};
|
||
mappingDefinitions = self.options.vim.plugin;
|
||
|
||
# addDescriptionsToMappings is a helper function from lib,
|
||
# that merges mapping values and their descriptions
|
||
# into one nice attribute set
|
||
mappings = addDescriptionsToMappings cfg.mappings mappingDefinitions;
|
||
in {
|
||
config = mkIf (cfg.enable) {
|
||
# ...
|
||
|
||
vim.maps.normal = mkMerge [
|
||
# mkSetBinding is another helper function from lib,
|
||
# that actually adds the mapping with a description.
|
||
(mkSetBinding mappings.findFiles "<cmd> Telescope find_files<CR>")
|
||
(mkSetBinding mappings.liveGrep "<cmd> Telescope live_grep<CR>")
|
||
(mkSetBinding mappings.buffers "<cmd> Telescope buffers<CR>")
|
||
(mkSetBinding mappings.helpTags "<cmd> Telescope help_tags<CR>")
|
||
(mkSetBinding mappings.open "<cmd> Telescope<CR>")
|
||
|
||
(mkSetBinding mappings.gitCommits "<cmd> Telescope git_commits<CR>")
|
||
(mkSetBinding mappings.gitBufferCommits "<cmd> Telescope git_bcommits<CR>")
|
||
(mkSetBinding mappings.gitBranches "<cmd> Telescope git_branches<CR>")
|
||
(mkSetBinding mappings.gitStatus "<cmd> Telescope git_status<CR>")
|
||
(mkSetBinding mappings.gitStash "<cmd> Telescope git_stash<CR>")
|
||
|
||
(mkIf config.vim.lsp.enable (mkMerge [
|
||
(mkSetBinding mappings.lspDocumentSymbols "<cmd> Telescope lsp_document_symbols<CR>")
|
||
(mkSetBinding mappings.lspWorkspaceSymbols "<cmd> Telescope lsp_workspace_symbols<CR>")
|
||
|
||
(mkSetBinding mappings.lspReferences "<cmd> Telescope lsp_references<CR>")
|
||
(mkSetBinding mappings.lspImplementations "<cmd> Telescope lsp_implementations<CR>")
|
||
(mkSetBinding mappings.lspDefinitions "<cmd> Telescope lsp_definitions<CR>")
|
||
(mkSetBinding mappings.lspTypeDefinitions "<cmd> Telescope lsp_type_definitions<CR>")
|
||
(mkSetBinding mappings.diagnostics "<cmd> Telescope diagnostics<CR>")
|
||
]))
|
||
|
||
(
|
||
mkIf config.vim.treesitter.enable
|
||
(mkSetBinding mappings.treesitter "<cmd> Telescope treesitter<CR>")
|
||
)
|
||
];
|
||
|
||
# ...
|
||
};
|
||
}</pre><div class="note"><h3 class="title">Note</h3><p>If you have come across a plugin that has an API that doesn’t seem to easily allow custom keybindings,
|
||
don’t be scared to implement a draft PR. We’ll help you get it done.</p></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sec-additional-plugins"></a>8.5. Adding Plugins</h2></div></div></div><p>To add a new neovim plugin, first add the source url in the inputs section of <code class="literal">flake.nix</code></p><pre class="programlisting nix">{
|
||
inputs = {
|
||
# ...
|
||
neodev-nvim = {
|
||
url = "github:folke/neodev.nvim";
|
||
flake = false;
|
||
};
|
||
};
|
||
}</pre><p>Then add the name of the plugin into the <code class="literal">availablePlugins</code> variable in <code class="literal">lib/types/plugins.nix</code>:</p><pre class="programlisting nix"># ...
|
||
availablePlugins = [
|
||
# ...
|
||
"neodev-nvim"
|
||
];</pre><p>You can now reference this plugin using its string name:</p><pre class="programlisting nix">config.vim.startPlugins = ["neodev-nvim"];</pre></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="options.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> Appendix A. Configuration Options</td></tr></table></div></body></html> |