node-client

by neovim

neovim / node-client

Nvim Node.js client and plugin host

221 Stars 34 Forks Last release: Not found MIT License 441 Commits 45 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

neovim-client

| CI (Linux, macOS, Windows) | Coverage | npm | Gitter | |----------------------------|----------|-----|--------| | Build Status | Coverage Badge | npm version | Gitter Badge |

Currently tested for node >= 10

Installation

Install the

neovim
package globally using
npm
.
npm install -g neovim

A global package is required for neovim to be able to communicate with a plugin.

Usage

This package exports a single

attach()
function which takes a pair of write/read streams and invokes a callback with a Nvim API object.

attach

const cp = require('child_process');
const attach = require('neovim').attach;

const nvim_proc = cp.spawn('nvim', ['-u', 'NONE', '-N', '--embed'], {});

// Attach to neovim process (async function() { const nvim = await attach({ proc: nvim_proc }); nvim.command('vsp'); nvim.command('vsp'); nvim.command('vsp'); const windows = await nvim.windows;

// expect(windows.length).toEqual(4); // expect(windows[0] instanceof nvim.Window).toEqual(true); // expect(windows[1] instanceof nvim.Window).toEqual(true);

nvim.window = windows[2]; const win = await nvim.window;

// expect(win).not.toEqual(windows[0]); // expect(win).toEqual(windows[2]);

const buf = await nvim.buffer; // expect(buf instanceof nvim.Buffer).toEqual(true);

const lines = await buf.lines; // expect(lines).toEqual(['']);

await buf.replace(['line1', 'line2'], 0); const newLines = await buf.lines; // expect(newLines).toEqual(['line1', 'line2']);

nvim.quit(); nvim_proc.disconnect(); })();

Writing a Plugin

A plugin can either be a file or folder in the

rplugin/node
directory. If the plugin is a folder, the
main
script from
package.json
will be loaded.

The plugin should export a function which takes a

NvimPlugin
object as its only parameter. You may then register autocmds, commands and functions by calling methods on the
NvimPlugin
object. You should not do any heavy initialisation or start any async functions at this stage, as nvim may only be collecting information about your plugin without wishing to actually use it. You should wait for one of your autocmds, commands or functions to be called before starting any processing.

console
has been replaced by a
winston
interface and
console.log
will call
winston.info
.

API

  NvimPlugin.nvim

This is the nvim api object you can use to send commands from your plugin to nvim.

  NvimPlugin.setOptions(options: NvimPluginOptions);

interface NvimPluginOptions { dev?: boolean; alwaysInit?: boolean; }

Set your plugin to dev mode, which will cause the module to be reloaded on each invocation.

alwaysInit
will always attempt to attempt to re-instantiate the plugin. e.g. your plugin class will always get called on each invocation of your plugin's command.
  NvimPlugin.registerAutocmd(name: string, fn: Function, options: AutocmdOptions): void;
  NvimPlugin.registerAutocmd(name: string, fn: [any, Function], options: AutocmdOptions): void;

interface AutocmdOptions { pattern: string; eval?: string; sync?: boolean; }

Registers an autocmd for the event

name
, calling your function
fn
with
options
. Pattern is the only required option. If you wish to call a method on an object you may pass
fn
as an array of
[object, object.method]
.

By default autocmds, commands and functions are all treated as asynchronous and should return

Promises
(or should be
async
functions).
  NvimPlugin.registerCommand(name: string, fn: Function, options?: CommandOptions): void;
  NvimPlugin.registerCommand(name: string, fn: [any, Function], options?: CommandOptions): void;

interface CommandOptions { sync?: boolean; range?: string; nargs?: string; }

Registers a command named by

name
, calling function
fn
with
options
. This will be invoked from nvim by entering
:name
in normal mode.
  NvimPlugin.registerFunction(name: string, fn: Function, options?: NvimFunctionOptions): void;
  NvimPlugin.registerFunction(name: string, fn: [any, Function], options?: NvimFunctionOptions): void;

interface NvimFunctionOptions { sync?: boolean; range?: string; eval?: string; }

Registers a function with name

name
, calling function
fn
with
options
. This will be invoked from nvim by entering eg
:call name()
in normal mode.

Examples

Examples of how to write plugins can be seen in the

examples
directory.

Debugging / troubleshooting

Here are a few env vars you can set while starting

neovim
, that can help debugging and configuring logging:

NVIM_NODE_HOST_DEBUG

Will spawn the node process that calls

neovim-client-host
with
--inspect-brk
so you can have a debugger. Pair that with this Node Inspector Manager Chrome plugin

Logging

Logging is done using

winston
through the
logger
module. Plugins have
console
replaced with this interface.

NVIM_NODE_LOG_LEVEL

Sets the logging level for winston. Default is

debug
, available levels are
{ error: 0, warn: 1, info: 2, verbose: 3, debug: 4, silly: 5 }

NVIM_NODE_LOG_FILE

Sets the log file path

Usage through node REPL

NVIM_LISTEN_ADDRESS

First, start Nvim with a known address (or use the $NVIMLISTENADDRESS of a running instance):

$ NVIMLISTENADDRESS=/tmp/nvim nvim In another terminal, connect a node REPL to Nvim

// `scripts/nvim` will detect if `NVIM_LISTEN_ADDRESS` is set and use that unix socket
// Otherwise will create an embedded `nvim` instance
require('neovim/scripts/nvim').then((nvim) => {
  nvim.command('vsp');
});

The tests and

scripts
can be consulted for more examples.

Contributors

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.