First Neovim plugin in Python

For some time I was (and still am) eager to write a Neovim plugin that would help me draw ASCII diagrams.

Neovim provides msgpack based RPC API which allows to communicate with editor over TCP/IP, Unix socket or pipe. Thus writing plugins in any language is possible. I used Python library implementing the API:

Controlling Neovim Instance

There are couple of ways how we can connect Python based plugin with Neovim. The easiest way is to start Neovim with specified Unix socket:

$ NVIM_LISTEN_ADDRESS=/tmp/nvim nvim

Now we can connect to Neovim instance from Python:

import neovim

vim = neovim.attach('socket', path='/tmp/nvim')
vim.current.line = 'New line'

python-client API

Neovim python API is not documented. While playing with it, I found some useful commands:

    Currently selected line content.

    Currently selected line number. Line indexes start from 1.

    Currently selected column number. Column indexes start from 1.

    Currently visible Neovim buffer.

buffer.append(line: str, index: int=-1) -> None
    Inserts specified line to the buffer.

    index - index of a line after which new line will be inserted.
        0 - inserts first line.
        -1 - inserts last line.

Configure Neovim to Load Plugin

We can tell Neovim to automatically load our Python based plugin. First of all our plugin must expose implement required API:

import neovim

class TestPlugin(object):
    def __init__(self, vim) -> None:
        self.vim = vim

    def alter_current_line(self) -> None:
        self.vim.current.line = 'New line'

This test plugin defines new Neovim command which simply overwrites current line.

Now to make Neovim load the plugin:

  1. Place it in ~/.config/nvim/rplugin/python3.

  2. Open Neovim and issue :UpdateRemotePlugins command.

  3. Restart Neovim.

Now select some line, press ESC and type :TestCommand. It should overwrite the line with "New Line".