Skip to content
This repository has been archived by the owner on Sep 9, 2022. It is now read-only.
/ nvimhost-d Public archive

⚡ nvim host plugin provider and API client library in D

License

Notifications You must be signed in to change notification settings

viniarck/nvimhost-d

Repository files navigation

pipeline status DUB Package

nvimhost-d

Neovim (nvim) host plugin provider and API client library in D.

nvimhostd-logo

Docs

The following snippets show how you can use this library, check out the examples for more information. This GIF shows the demo-plugin below in action:

screencast

Goals

  • Provide a library for high-performance plugins (it takes between 2-4ms on average via msgpack RPC to call a function).
  • Provide an API for other projects to integrate with nvim.

Plugin snippet demo

import nvimhost.plugin;
import nvimhost.api;

struct DemoPlugin {

    NvimAPI nvim;

    this(ref NvimAPI nvim) {
        this.nvim = nvim;
    }

    // sync function with one argument
    @NvimFunc("Greet")
    string greet(string name) {
        return "Hello " ~ name;
    }

    // sync function with multiple arguments
    @NvimFunc("SumBeginToEnd")
    int sumBeginToEnd(int begin, int end) {
        import std.range;
        import std.algorithm.iteration;
        import std.stdio;

        return cast(int) iota(begin, end).sum();
    }

    // sync function calling async (non blocking) nvim functions
    @NvimFunc("SetVarValueSync")
    int setVarValue(int i) {
        import std.conv;

        nvim.commandAsync("let g:test_var_value=" ~ i.to!string);
        return i;
    }

    // async function calling both async and sync nvim functions
    @NvimFunc("SetVarValueAsync", Async)
    void setVarValueAsync(int i) {
        import std.conv;

        nvim.commandAsync("let g:testasync_var_value=" ~ i.to!string);
        nvim.command("echomsg 'hello world sync!'");
    }

}

void main() {

    // make sure you source this .vim file in neovim, since this will bootstrap
    // the binary and register the plugin
    auto pluginDstFile = "~/.config/nvim/settings/demo-plugin.vim";
    // template instantiate DemoPlugin
    auto plugin = NvimPlugin!(DemoPlugin)("demo-plugin", pluginDstFile);
    // keep it running
    scope (exit) {
        plugin.keepRunning();
    }
}

API client snippet demo

void main() {
    import std.stdio;
    import nvimhost.api : NvimAPI;
    auto nvim = NvimAPI();
    nvim.enableLog();

    // Calling a simple command on Neovim
    nvim.command("echomsg 'hello world!'");

    // Iterating over loaded buffers
    auto buffers = nvim.vimGetBuffers();
    foreach (buffer; buffers) {
        writeln("buffer #", buffer);
    }
}

You can find the code documentation generated by the dub registry here.

How to install and build

  • Fetch it using dub, and use it as a library in your source code by importing the nvimhost package:
dub fetch nvimhost
dub build nvimhost --build=release

For more information about building binaries, check out the .gitlab-ci.yml file

How to ship plugin binaries

Either:

  • Your users compile the binary using ldc2/dmd or
  • You pre-compile dynamically linked binaries for the platforms you want to target.

Based on the current build settings, the dynamic linked binary will depend on common C libraries such as libc.so.6, libpthread.so.0, and a few others, which are expected to be present on most Unix distributions, so it should run without any issues.

Trying out linux x86_64 compiled binaries

If you want to try out the demo-plugin, I've pre-compiled the binary for linux x86_64:

  • curl -LO https://github.com/viniarck/nvimhost-d/releases/download/v1.1.1/demo-plugin
  • chmod +x demo-plugin
  • sudo mv demo-plugin /usr/local/bin (or somewhere else in your PATH)
  • demo-plugin (execute the plugin once in your shell to generate the manifest)
  • In your ~/.config/nvim/init.vim file, source ~/.config/nvim/settings/demo-plugin.vim

From this point forward, all plugin functions will be available to be called from nvim

  • Launch nvim and call native D functions from this plugin, for example, :call Greet("D")

Testing

Both unit tests and system tests (end-to-end) testing with nvim have been automated in the CI.