Name: node-client
Owner: Neovim
Description: Nvim Node.js client and plugin host
Created: 2015-02-11 14:23:57.0
Updated: 2018-05-24 12:30:16.0
Pushed: 2018-05-24 12:30:33.0
Size: 585
Language: TypeScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
| CI (Linux, macOS) | CI (Windows) | Coverage | npm | Gitter | |——————-|————–|———-|—–|——–| | | | | | |
Currently tested for node >= 8
Install the neovim
package globally using npm
.
install -g neovim
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
t cp = require('child_process');
t attach = require('neovim').attach;
t nvim_proc = cp.spawn('nvim', ['-u', 'NONE', '-N', '--embed'], {});
ttach to neovim process
nc function() {
nst nvim = await attach({ proc: nvim_proc });
im.command('vsp');
im.command('vsp');
im.command('vsp');
nst 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);
im.window = windows[2];
nst win = await nvim.window;
expect(win).not.toEqual(windows[0]);
expect(win).toEqual(windows[2]);
nst buf = await nvim.buffer;
expect(buf instanceof nvim.Buffer).toEqual(true);
nst lines = await buf.lines;
expect(lines).toEqual(['']);
ait buf.replace(['line1', 'line2'], 0);
nst newLines = await buf.lines;
expect(newLines).toEqual(['line1', 'line2']);
im.quit();
im_proc.disconnect();
;
If you are a plugin developer, I'd love to hear your feedback on the plugin API.
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 it's 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
.
imPlugin.nvim
This is the nvim api object you can use to send commands from your plugin to vim.
imPlugin.setOptions(options: NvimPluginOptions);
terface NvimPluginOptions {
dev?: boolean;
Set your plugin to dev mode, which will cause the module to be reloaded on each invokation.
imPlugin.registerAutocmd(name: string, fn: Function, options: AutocmdOptions): void;
imPlugin.registerAutocmd(name: string, fn: [any, Function], options: AutocmdOptions): void;
terface 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).
imPlugin.registerCommand(name: string, fn: Function, options?: CommandOptions): void;
imPlugin.registerCommand(name: string, fn: [any, Function], options?: CommandOptions): void;
terface 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.
imPlugin.registerFunction(name: string, fn: Function, options?: NvimFunctionOptions): void;
imPlugin.registerFunction(name: string, fn: [any, Function], options?: NvimFunctionOptions): void;
terface 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.
tion onBufWrite() {
nsole.log('Buffer written!');
le.exports = (plugin) => {
ugin.registerAutocmd('BufWritePre', onBufWrite, { pattern: '*' });
s MyPlugin {
nstructor(plugin) {
this.plugin = plugin;
plugin.registerCommand('SetMyLine', [this, this.setLine]);
tLine() {
this.plugin.nvim.setLine('A line, for your troubles');
le.exports = (plugin) => new MyPlugin(plugin);
r for convenience, exporting the class itself is equivalent to the above
le.exports = MyPlugin;
tion MyPlugin(plugin) {
is.plugin = plugin;
ugin.registerFunction('MyFunc', [this, MyPlugin.prototype.func]);
ugin.prototype.func = function() {
is.plugin.nvim.setLine('A line, for your troubles');
rt default MyPlugin;
r
rt default (plugin) => new MyPlugin(plugin);
The decorator api is still supported. The NvimPlugin
object is passed as a second parameter in case you wish to dynamically register further commands in the constructor.
rt { Plugin, Function, Autocmd, Command } from 'neovim';
f `Plugin` decorator can be called with options
gin({ dev: true })
rt default class TestPlugin {
nstructor(nvim, plugin) {
unction('Vsplit', { sync: true })
litMe(args, done) {
this.nvim.command('vsplit');
ommand('LongCommand')
ync longCommand(args) {
console.log('Output will be routed to $NVIM_NODE_LOG_FILE');
const bufferName = await this.nvim.buffer.name;
return bufferName;
ommand('UsePromises')
omiseExample() {
return this.nvim.buffer.name.then((name) => {
console.log(`Current buffer name is ${name}`);
});
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 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
NVIM_LISTEN_ADDRESS
First, start Nvim with a known address (or use the $NVIM_LISTEN_ADDRESS of a running instance):
$ NVIM_LISTEN_ADDRESS=/tmp/nvim nvim In another terminal, connect a node REPL to Nvim
nvim;
scripts/nvim` will detect if `NVIM_LISTEN_ADDRESS` is set and use that unix socket
therwise will create an embedded `nvim` instance
ire('neovim/scripts/nvim').then((n) => nvim = n);
.command('vsp');
The tests and scripts
can be consulted for more examples.