neovim.api module
Nvim API subpackage.
This package implements a higher-level API that wraps msgpack-rpc Session
instances.
"""Nvim API subpackage.
This package implements a higher-level API that wraps msgpack-rpc `Session`
instances.
"""
from .buffer import Buffer
from .common import decode_if_bytes, walk
from .nvim import Nvim, NvimError
from .tabpage import Tabpage
from .window import Window
__all__ = ('Nvim', 'Buffer', 'Window', 'Tabpage', 'NvimError',
'decode_if_bytes', 'walk')
Functions
def decode_if_bytes(
obj, mode=True)
Decode obj if it is bytes.
def decode_if_bytes(obj, mode=True):
"""Decode obj if it is bytes."""
if mode is True:
mode = unicode_errors_default
if isinstance(obj, bytes):
return obj.decode("utf-8", errors=mode)
return obj
def walk(
fn, obj, *args, **kwargs)
Recursively walk an object graph applying fn
/args
to objects.
def walk(fn, obj, *args, **kwargs):
"""Recursively walk an object graph applying `fn`/`args` to objects."""
if type(obj) in [list, tuple]:
return list(walk(fn, o, *args) for o in obj)
if type(obj) is dict:
return dict((walk(fn, k, *args), walk(fn, v, *args)) for k, v in
obj.items())
return fn(obj, *args, **kwargs)
Classes
class Buffer
A remote Nvim buffer.
class Buffer(Remote):
"""A remote Nvim buffer."""
_api_prefix = "nvim_buf_"
def __len__(self):
"""Return the number of lines contained in a Buffer."""
return self.request('buffer_line_count')
def __getitem__(self, idx):
"""Get a buffer line or slice by integer index.
Indexes may be negative to specify positions from the end of the
buffer. For example, -1 is the last line, -2 is the line before that
and so on.
When retrieving slices, omiting indexes(eg: `buffer[:]`) will bring
the whole buffer.
"""
if not isinstance(idx, slice):
i = adjust_index(idx)
return self.request('nvim_buf_get_lines', i, i + 1, True)[0]
start = adjust_index(idx.start, 0)
end = adjust_index(idx.stop, -1)
return self.request('nvim_buf_get_lines', start, end, False)
def __setitem__(self, idx, item):
"""Replace a buffer line or slice by integer index.
Like with `__getitem__`, indexes may be negative.
When replacing slices, omiting indexes(eg: `buffer[:]`) will replace
the whole buffer.
"""
if not isinstance(idx, slice):
i = adjust_index(idx)
lines = [item] if item is not None else []
return self.request('nvim_buf_set_lines', i, i + 1, True, lines)
lines = item if item is not None else []
start = adjust_index(idx.start, 0)
end = adjust_index(idx.stop, -1)
return self.request('buffer_set_lines', start, end, False, lines)
def __iter__(self):
"""Iterate lines of a buffer.
This will retrieve all lines locally before iteration starts. This
approach is used because for most cases, the gain is much greater by
minimizing the number of API calls by transfering all data needed to
work.
"""
lines = self[:]
for line in lines:
yield line
def __delitem__(self, idx):
"""Delete line or slice of lines from the buffer.
This is the same as __setitem__(idx, [])
"""
self.__setitem__(idx, None)
def append(self, lines, index=-1):
"""Append a string or list of lines to the buffer."""
if isinstance(lines, (basestring, bytes)):
lines = [lines]
return self.request('nvim_buf_set_lines', index, index, True, lines)
def mark(self, name):
"""Return (row, col) tuple for a named mark."""
return self.request('nvim_buf_get_mark', name)
def range(self, start, end):
"""Return a `Range` object, which represents part of the Buffer."""
return Range(self, start, end)
def add_highlight(self, hl_group, line, col_start=0,
col_end=-1, src_id=-1, async=None):
"""Add a highlight to the buffer."""
if async is None:
async = (src_id != 0)
return self.request('nvim_buf_add_highlight', src_id, hl_group,
line, col_start, col_end, async=async)
def clear_highlight(self, src_id, line_start=0, line_end=-1, async=True):
"""Clear highlights from the buffer."""
self.request('nvim_buf_clear_highlight', src_id,
line_start, line_end, async=async)
@property
def name(self):
"""Get the buffer name."""
return self.request('nvim_buf_get_name')
@name.setter
def name(self, value):
"""Set the buffer name. BufFilePre/BufFilePost are triggered."""
return self.request('nvim_buf_set_name', value)
@property
def valid(self):
"""Return True if the buffer still exists."""
return self.request('nvim_buf_is_valid')
@property
def number(self):
"""Get the buffer number."""
return self.handle
Ancestors (in MRO)
- Buffer
- neovim.api.common.Remote
- builtins.object
Static methods
def __init__(
self, session, code_data)
Initialize from session and code_data immutable object.
The code_data
contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
def __init__(self, session, code_data):
"""Initialize from session and code_data immutable object.
The `code_data` contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
"""
self._session = session
self.code_data = code_data
self.handle = unpackb(code_data[1])
self.api = RemoteApi(self, self._api_prefix)
self.vars = RemoteMap(self, self._api_prefix + 'get_var',
self._api_prefix + 'set_var')
self.options = RemoteMap(self, self._api_prefix + 'get_option',
self._api_prefix + 'set_option')
def add_highlight(
self, hl_group, line, col_start=0, col_end=-1, src_id=-1, async=None)
Add a highlight to the buffer.
def add_highlight(self, hl_group, line, col_start=0,
col_end=-1, src_id=-1, async=None):
"""Add a highlight to the buffer."""
if async is None:
async = (src_id != 0)
return self.request('nvim_buf_add_highlight', src_id, hl_group,
line, col_start, col_end, async=async)
def append(
self, lines, index=-1)
Append a string or list of lines to the buffer.
def append(self, lines, index=-1):
"""Append a string or list of lines to the buffer."""
if isinstance(lines, (basestring, bytes)):
lines = [lines]
return self.request('nvim_buf_set_lines', index, index, True, lines)
def clear_highlight(
self, src_id, line_start=0, line_end=-1, async=True)
Clear highlights from the buffer.
def clear_highlight(self, src_id, line_start=0, line_end=-1, async=True):
"""Clear highlights from the buffer."""
self.request('nvim_buf_clear_highlight', src_id,
line_start, line_end, async=async)
def mark(
self, name)
Return (row, col) tuple for a named mark.
def mark(self, name):
"""Return (row, col) tuple for a named mark."""
return self.request('nvim_buf_get_mark', name)
def range(
self, start, end)
Return a Range
object, which represents part of the Buffer.
def range(self, start, end):
"""Return a `Range` object, which represents part of the Buffer."""
return Range(self, start, end)
def request(
self, name, *args, **kwargs)
Wrapper for nvim.request.
def request(self, name, *args, **kwargs):
"""Wrapper for nvim.request."""
return self._session.request(name, self, *args, **kwargs)
Instance variables
var name
Get the buffer name.
var number
Get the buffer number.
var valid
Return True if the buffer still exists.
class Nvim
Class that represents a remote Nvim instance.
This class is main entry point to Nvim remote API, it is a wrapper around Session instances.
The constructor of this class must not be called directly. Instead, the
from_session
class method should be used to create the first instance
from a raw Session
instance.
Subsequent instances for the same session can be created by calling the
with_decode
instance method to change the decoding behavior or
SubClass.from_nvim(nvim)
where SubClass
is a subclass of Nvim
, which
is useful for having multiple Nvim
objects that behave differently
without one affecting the other.
class Nvim(object):
"""Class that represents a remote Nvim instance.
This class is main entry point to Nvim remote API, it is a wrapper
around Session instances.
The constructor of this class must not be called directly. Instead, the
`from_session` class method should be used to create the first instance
from a raw `Session` instance.
Subsequent instances for the same session can be created by calling the
`with_decode` instance method to change the decoding behavior or
`SubClass.from_nvim(nvim)` where `SubClass` is a subclass of `Nvim`, which
is useful for having multiple `Nvim` objects that behave differently
without one affecting the other.
"""
@classmethod
def from_session(cls, session):
"""Create a new Nvim instance for a Session instance.
This method must be called to create the first Nvim instance, since it
queries Nvim metadata for type information and sets a SessionHook for
creating specialized objects from Nvim remote handles.
"""
session.error_wrapper = lambda e: NvimError(e[1])
channel_id, metadata = session.request(b'vim_get_api_info')
if IS_PYTHON3:
# decode all metadata strings for python3
metadata = walk(decode_if_bytes, metadata)
types = {
metadata['types']['Buffer']['id']: Buffer,
metadata['types']['Window']['id']: Window,
metadata['types']['Tabpage']['id']: Tabpage,
}
return cls(session, channel_id, metadata, types)
@classmethod
def from_nvim(cls, nvim):
"""Create a new Nvim instance from an existing instance."""
return cls(nvim._session, nvim.channel_id, nvim.metadata,
nvim.types, nvim._decode, nvim._err_cb)
def __init__(self, session, channel_id, metadata, types,
decode=False, err_cb=None):
"""Initialize a new Nvim instance. This method is module-private."""
self._session = session
self.channel_id = channel_id
self.metadata = metadata
version = metadata.get("version", {"api_level": 0})
self.version = Version(**version)
self.types = types
self.api = RemoteApi(self, 'nvim_')
self.vars = RemoteMap(self, 'nvim_get_var', 'nvim_set_var')
self.vvars = RemoteMap(self, 'vim_get_vvar', None)
self.options = RemoteMap(self, 'nvim_get_option', 'nvim_set_option')
self.buffers = Buffers(self)
self.windows = RemoteSequence(self, 'nvim_list_wins')
self.tabpages = RemoteSequence(self, 'nvim_list_tabpages')
self.current = Current(self)
self.session = CompatibilitySession(self)
self.funcs = Funcs(self)
self.error = NvimError
self._decode = decode
self._err_cb = err_cb
def _from_nvim(self, obj, decode=None):
if decode is None:
decode = self._decode
if type(obj) is ExtType:
cls = self.types[obj.code]
return cls(self, (obj.code, obj.data))
if decode:
obj = decode_if_bytes(obj, decode)
return obj
def _to_nvim(self, obj):
if isinstance(obj, Remote):
return ExtType(*obj.code_data)
return obj
def request(self, name, *args, **kwargs):
r"""Send an API request or notification to nvim.
It is rarely needed to call this function directly, as most API
functions have python wrapper functions. The `api` object can
be also be used to call API functions as methods:
vim.api.err_write('ERROR\n', async=True)
vim.current.buffer.api.get_mark('.')
is equivalent to
vim.request('nvim_err_write', 'ERROR\n', async=True)
vim.request('nvim_buf_get_mark', vim.current.buffer, '.')
Normally a blocking request will be sent. If the `async` flag is
present and True, a asynchronous notification is sent instead. This
will never block, and the return value or error is ignored.
"""
decode = kwargs.pop('decode', self._decode)
args = walk(self._to_nvim, args)
res = self._session.request(name, *args, **kwargs)
return walk(self._from_nvim, res, decode=decode)
def next_message(self):
"""Block until a message(request or notification) is available.
If any messages were previously enqueued, return the first in queue.
If not, run the event loop until one is received.
"""
msg = self._session.next_message()
if msg:
return walk(self._from_nvim, msg)
def run_loop(self, request_cb, notification_cb,
setup_cb=None, err_cb=None):
"""Run the event loop to receive requests and notifications from Nvim.
This should not be called from a plugin running in the host, which
already runs the loop and dispatches events to plugins.
"""
if err_cb is None:
err_cb = sys.stderr.write
self._err_cb = err_cb
def filter_request_cb(name, args):
name = self._from_nvim(name)
args = walk(self._from_nvim, args)
try:
result = request_cb(name, args)
except Exception:
msg = ("error caught in request handler '{} {}'\n{}\n\n"
.format(name, args, format_exc_skip(1)))
self._err_cb(msg)
raise
return walk(self._to_nvim, result)
def filter_notification_cb(name, args):
name = self._from_nvim(name)
args = walk(self._from_nvim, args)
try:
notification_cb(name, args)
except Exception:
msg = ("error caught in notification handler '{} {}'\n{}\n\n"
.format(name, args, format_exc_skip(1)))
self._err_cb(msg)
raise
self._session.run(filter_request_cb, filter_notification_cb, setup_cb)
def stop_loop(self):
"""Stop the event loop being started with `run_loop`."""
self._session.stop()
def with_decode(self, decode=True):
"""Initialize a new Nvim instance."""
return Nvim(self._session, self.channel_id,
self.metadata, self.types, decode, self._err_cb)
def ui_attach(self, width, height, rgb):
"""Register as a remote UI.
After this method is called, the client will receive redraw
notifications.
"""
return self.request('ui_attach', width, height, rgb)
def ui_detach(self):
"""Unregister as a remote UI."""
return self.request('ui_detach')
def ui_try_resize(self, width, height):
"""Notify nvim that the client window has resized.
If possible, nvim will send a redraw request to resize.
"""
return self.request('ui_try_resize', width, height)
def subscribe(self, event):
"""Subscribe to a Nvim event."""
return self.request('nvim_subscribe', event)
def unsubscribe(self, event):
"""Unsubscribe to a Nvim event."""
return self.request('nvim_unsubscribe', event)
def command(self, string, **kwargs):
"""Execute a single ex command."""
return self.request('nvim_command', string, **kwargs)
def command_output(self, string):
"""Execute a single ex command and return the output."""
return self.request('nvim_command_output', string)
def eval(self, string, **kwargs):
"""Evaluate a vimscript expression."""
return self.request('nvim_eval', string, **kwargs)
def call(self, name, *args, **kwargs):
"""Call a vimscript function."""
return self.request('nvim_call_function', name, args, **kwargs)
def strwidth(self, string):
"""Return the number of display cells `string` occupies.
Tab is counted as one cell.
"""
return self.request('nvim_strwidth', string)
def list_runtime_paths(self):
"""Return a list of paths contained in the 'runtimepath' option."""
return self.request('nvim_list_runtime_paths')
def foreach_rtp(self, cb):
"""Invoke `cb` for each path in 'runtimepath'.
Call the given callable for each path in 'runtimepath' until either
callable returns something but None, the exception is raised or there
are no longer paths. If stopped in case callable returned non-None,
vim.foreach_rtp function returns the value returned by callable.
"""
for path in self.request('nvim_list_runtime_paths'):
try:
if cb(path) is not None:
break
except Exception:
break
def chdir(self, dir_path):
"""Run os.chdir, then all appropriate vim stuff."""
os_chdir(dir_path)
return self.request('nvim_set_current_dir', dir_path)
def feedkeys(self, keys, options='', escape_csi=True):
"""Push `keys` to Nvim user input buffer.
Options can be a string with the following character flags:
- 'm': Remap keys. This is default.
- 'n': Do not remap keys.
- 't': Handle keys as if typed; otherwise they are handled as if coming
from a mapping. This matters for undo, opening folds, etc.
"""
return self.request('nvim_feedkeys', keys, options, escape_csi)
def input(self, bytes):
"""Push `bytes` to Nvim low level input buffer.
Unlike `feedkeys()`, this uses the lowest level input buffer and the
call is not deferred. It returns the number of bytes actually
written(which can be less than what was requested if the buffer is
full).
"""
return self.request('nvim_input', bytes)
def replace_termcodes(self, string, from_part=False, do_lt=True,
special=True):
r"""Replace any terminal code strings by byte sequences.
The returned sequences are Nvim's internal representation of keys,
for example:
-> '\x1b'
-> '\r'
-> '\x0c'
-> '\x80ku'
The returned sequences can be used as input to `feedkeys`.
"""
return self.request('vim_replace_termcodes', string,
from_part, do_lt, special)
def out_write(self, msg):
"""Print `msg` as a normal message."""
return self.request('nvim_out_write', msg)
def err_write(self, msg, **kwargs):
"""Print `msg` as an error message."""
return self.request('nvim_err_write', msg, **kwargs)
def quit(self, quit_command='qa!'):
"""Send a quit command to Nvim.
By default, the quit command is 'qa!' which will make Nvim quit without
saving anything.
"""
try:
self.command(quit_command)
except IOError:
# sending a quit command will raise an IOError because the
# connection is closed before a response is received. Safe to
# ignore it.
pass
def new_highlight_source(self):
"""Return new src_id for use with Buffer.add_highlight."""
return self.current.buffer.add_highlight("", 0, src_id=0)
def async_call(self, fn, *args, **kwargs):
"""Schedule `fn` to be called by the event loop soon.
This function is thread-safe, and is the only way code not
on the main thread could interact with nvim api objects.
This function can also be called in a synchronous
event handler, just before it returns, to defer execution
that shouldn't block neovim.
"""
call_point = ''.join(format_stack(None, 5)[:-1])
def handler():
try:
fn(*args, **kwargs)
except Exception as err:
msg = ("error caught while executing async callback:\n"
"{!r}\n{}\n \nthe call was requested at\n{}"
.format(err, format_exc_skip(1), call_point))
self._err_cb(msg)
raise
self._session.threadsafe_call(handler)
Ancestors (in MRO)
- Nvim
- builtins.object
Static methods
def __init__(
self, session, channel_id, metadata, types, decode=False, err_cb=None)
Initialize a new Nvim instance. This method is module-private.
def __init__(self, session, channel_id, metadata, types,
decode=False, err_cb=None):
"""Initialize a new Nvim instance. This method is module-private."""
self._session = session
self.channel_id = channel_id
self.metadata = metadata
version = metadata.get("version", {"api_level": 0})
self.version = Version(**version)
self.types = types
self.api = RemoteApi(self, 'nvim_')
self.vars = RemoteMap(self, 'nvim_get_var', 'nvim_set_var')
self.vvars = RemoteMap(self, 'vim_get_vvar', None)
self.options = RemoteMap(self, 'nvim_get_option', 'nvim_set_option')
self.buffers = Buffers(self)
self.windows = RemoteSequence(self, 'nvim_list_wins')
self.tabpages = RemoteSequence(self, 'nvim_list_tabpages')
self.current = Current(self)
self.session = CompatibilitySession(self)
self.funcs = Funcs(self)
self.error = NvimError
self._decode = decode
self._err_cb = err_cb
def async_call(
self, fn, *args, **kwargs)
Schedule fn
to be called by the event loop soon.
This function is thread-safe, and is the only way code not on the main thread could interact with nvim api objects.
This function can also be called in a synchronous event handler, just before it returns, to defer execution that shouldn't block neovim.
def async_call(self, fn, *args, **kwargs):
"""Schedule `fn` to be called by the event loop soon.
This function is thread-safe, and is the only way code not
on the main thread could interact with nvim api objects.
This function can also be called in a synchronous
event handler, just before it returns, to defer execution
that shouldn't block neovim.
"""
call_point = ''.join(format_stack(None, 5)[:-1])
def handler():
try:
fn(*args, **kwargs)
except Exception as err:
msg = ("error caught while executing async callback:\n"
"{!r}\n{}\n \nthe call was requested at\n{}"
.format(err, format_exc_skip(1), call_point))
self._err_cb(msg)
raise
self._session.threadsafe_call(handler)
def call(
self, name, *args, **kwargs)
Call a vimscript function.
def call(self, name, *args, **kwargs):
"""Call a vimscript function."""
return self.request('nvim_call_function', name, args, **kwargs)
def chdir(
self, dir_path)
Run os.chdir, then all appropriate vim stuff.
def chdir(self, dir_path):
"""Run os.chdir, then all appropriate vim stuff."""
os_chdir(dir_path)
return self.request('nvim_set_current_dir', dir_path)
def command(
self, string, **kwargs)
Execute a single ex command.
def command(self, string, **kwargs):
"""Execute a single ex command."""
return self.request('nvim_command', string, **kwargs)
def command_output(
self, string)
Execute a single ex command and return the output.
def command_output(self, string):
"""Execute a single ex command and return the output."""
return self.request('nvim_command_output', string)
def err_write(
self, msg, **kwargs)
Print msg
as an error message.
def err_write(self, msg, **kwargs):
"""Print `msg` as an error message."""
return self.request('nvim_err_write', msg, **kwargs)
def eval(
self, string, **kwargs)
Evaluate a vimscript expression.
def eval(self, string, **kwargs):
"""Evaluate a vimscript expression."""
return self.request('nvim_eval', string, **kwargs)
def feedkeys(
self, keys, options='', escape_csi=True)
Push keys
to Nvim user input buffer.
Options can be a string with the following character flags: - 'm': Remap keys. This is default. - 'n': Do not remap keys. - 't': Handle keys as if typed; otherwise they are handled as if coming from a mapping. This matters for undo, opening folds, etc.
def feedkeys(self, keys, options='', escape_csi=True):
"""Push `keys` to Nvim user input buffer.
Options can be a string with the following character flags:
- 'm': Remap keys. This is default.
- 'n': Do not remap keys.
- 't': Handle keys as if typed; otherwise they are handled as if coming
from a mapping. This matters for undo, opening folds, etc.
"""
return self.request('nvim_feedkeys', keys, options, escape_csi)
def foreach_rtp(
self, cb)
Invoke cb
for each path in 'runtimepath'.
Call the given callable for each path in 'runtimepath' until either callable returns something but None, the exception is raised or there are no longer paths. If stopped in case callable returned non-None, vim.foreach_rtp function returns the value returned by callable.
def foreach_rtp(self, cb):
"""Invoke `cb` for each path in 'runtimepath'.
Call the given callable for each path in 'runtimepath' until either
callable returns something but None, the exception is raised or there
are no longer paths. If stopped in case callable returned non-None,
vim.foreach_rtp function returns the value returned by callable.
"""
for path in self.request('nvim_list_runtime_paths'):
try:
if cb(path) is not None:
break
except Exception:
break
def input(
self, bytes)
Push bytes
to Nvim low level input buffer.
Unlike feedkeys()
, this uses the lowest level input buffer and the
call is not deferred. It returns the number of bytes actually
written(which can be less than what was requested if the buffer is
full).
def input(self, bytes):
"""Push `bytes` to Nvim low level input buffer.
Unlike `feedkeys()`, this uses the lowest level input buffer and the
call is not deferred. It returns the number of bytes actually
written(which can be less than what was requested if the buffer is
full).
"""
return self.request('nvim_input', bytes)
def list_runtime_paths(
self)
Return a list of paths contained in the 'runtimepath' option.
def list_runtime_paths(self):
"""Return a list of paths contained in the 'runtimepath' option."""
return self.request('nvim_list_runtime_paths')
def new_highlight_source(
self)
Return new src_id for use with Buffer.add_highlight.
def new_highlight_source(self):
"""Return new src_id for use with Buffer.add_highlight."""
return self.current.buffer.add_highlight("", 0, src_id=0)
def next_message(
self)
Block until a message(request or notification) is available.
If any messages were previously enqueued, return the first in queue. If not, run the event loop until one is received.
def next_message(self):
"""Block until a message(request or notification) is available.
If any messages were previously enqueued, return the first in queue.
If not, run the event loop until one is received.
"""
msg = self._session.next_message()
if msg:
return walk(self._from_nvim, msg)
def out_write(
self, msg)
Print msg
as a normal message.
def out_write(self, msg):
"""Print `msg` as a normal message."""
return self.request('nvim_out_write', msg)
def quit(
self, quit_command='qa!')
Send a quit command to Nvim.
By default, the quit command is 'qa!' which will make Nvim quit without saving anything.
def quit(self, quit_command='qa!'):
"""Send a quit command to Nvim.
By default, the quit command is 'qa!' which will make Nvim quit without
saving anything.
"""
try:
self.command(quit_command)
except IOError:
# sending a quit command will raise an IOError because the
# connection is closed before a response is received. Safe to
# ignore it.
pass
def replace_termcodes(
self, string, from_part=False, do_lt=True, special=True)
Replace any terminal code strings by byte sequences.
The returned sequences are Nvim's internal representation of keys, for example:
The returned sequences can be used as input to feedkeys
.
def replace_termcodes(self, string, from_part=False, do_lt=True,
special=True):
r"""Replace any terminal code strings by byte sequences.
The returned sequences are Nvim's internal representation of keys,
for example:
-> '\x1b'
-> '\r'
-> '\x0c'
-> '\x80ku'
The returned sequences can be used as input to `feedkeys`.
"""
return self.request('vim_replace_termcodes', string,
from_part, do_lt, special)
def request(
self, name, *args, **kwargs)
Send an API request or notification to nvim.
It is rarely needed to call this function directly, as most API
functions have python wrapper functions. The api
object can
be also be used to call API functions as methods:
vim.api.err_write('ERROR\n', async=True)
vim.current.buffer.api.get_mark('.')
is equivalent to
vim.request('nvim_err_write', 'ERROR\n', async=True)
vim.request('nvim_buf_get_mark', vim.current.buffer, '.')
Normally a blocking request will be sent. If the async
flag is
present and True, a asynchronous notification is sent instead. This
will never block, and the return value or error is ignored.
def request(self, name, *args, **kwargs):
r"""Send an API request or notification to nvim.
It is rarely needed to call this function directly, as most API
functions have python wrapper functions. The `api` object can
be also be used to call API functions as methods:
vim.api.err_write('ERROR\n', async=True)
vim.current.buffer.api.get_mark('.')
is equivalent to
vim.request('nvim_err_write', 'ERROR\n', async=True)
vim.request('nvim_buf_get_mark', vim.current.buffer, '.')
Normally a blocking request will be sent. If the `async` flag is
present and True, a asynchronous notification is sent instead. This
will never block, and the return value or error is ignored.
"""
decode = kwargs.pop('decode', self._decode)
args = walk(self._to_nvim, args)
res = self._session.request(name, *args, **kwargs)
return walk(self._from_nvim, res, decode=decode)
def run_loop(
self, request_cb, notification_cb, setup_cb=None, err_cb=None)
Run the event loop to receive requests and notifications from Nvim.
This should not be called from a plugin running in the host, which already runs the loop and dispatches events to plugins.
def run_loop(self, request_cb, notification_cb,
setup_cb=None, err_cb=None):
"""Run the event loop to receive requests and notifications from Nvim.
This should not be called from a plugin running in the host, which
already runs the loop and dispatches events to plugins.
"""
if err_cb is None:
err_cb = sys.stderr.write
self._err_cb = err_cb
def filter_request_cb(name, args):
name = self._from_nvim(name)
args = walk(self._from_nvim, args)
try:
result = request_cb(name, args)
except Exception:
msg = ("error caught in request handler '{} {}'\n{}\n\n"
.format(name, args, format_exc_skip(1)))
self._err_cb(msg)
raise
return walk(self._to_nvim, result)
def filter_notification_cb(name, args):
name = self._from_nvim(name)
args = walk(self._from_nvim, args)
try:
notification_cb(name, args)
except Exception:
msg = ("error caught in notification handler '{} {}'\n{}\n\n"
.format(name, args, format_exc_skip(1)))
self._err_cb(msg)
raise
self._session.run(filter_request_cb, filter_notification_cb, setup_cb)
def stop_loop(
self)
Stop the event loop being started with run_loop
.
def stop_loop(self):
"""Stop the event loop being started with `run_loop`."""
self._session.stop()
def strwidth(
self, string)
Return the number of display cells string
occupies.
Tab is counted as one cell.
def strwidth(self, string):
"""Return the number of display cells `string` occupies.
Tab is counted as one cell.
"""
return self.request('nvim_strwidth', string)
def subscribe(
self, event)
Subscribe to a Nvim event.
def subscribe(self, event):
"""Subscribe to a Nvim event."""
return self.request('nvim_subscribe', event)
def ui_attach(
self, width, height, rgb)
Register as a remote UI.
After this method is called, the client will receive redraw notifications.
def ui_attach(self, width, height, rgb):
"""Register as a remote UI.
After this method is called, the client will receive redraw
notifications.
"""
return self.request('ui_attach', width, height, rgb)
def ui_detach(
self)
Unregister as a remote UI.
def ui_detach(self):
"""Unregister as a remote UI."""
return self.request('ui_detach')
def ui_try_resize(
self, width, height)
Notify nvim that the client window has resized.
If possible, nvim will send a redraw request to resize.
def ui_try_resize(self, width, height):
"""Notify nvim that the client window has resized.
If possible, nvim will send a redraw request to resize.
"""
return self.request('ui_try_resize', width, height)
def unsubscribe(
self, event)
Unsubscribe to a Nvim event.
def unsubscribe(self, event):
"""Unsubscribe to a Nvim event."""
return self.request('nvim_unsubscribe', event)
def with_decode(
self, decode=True)
Initialize a new Nvim instance.
def with_decode(self, decode=True):
"""Initialize a new Nvim instance."""
return Nvim(self._session, self.channel_id,
self.metadata, self.types, decode, self._err_cb)
Instance variables
var api
var buffers
var channel_id
var current
var error
var funcs
var metadata
var options
var session
var tabpages
var types
var vars
var version
var vvars
var windows
Methods
def from_nvim(
cls, nvim)
Create a new Nvim instance from an existing instance.
@classmethod
def from_nvim(cls, nvim):
"""Create a new Nvim instance from an existing instance."""
return cls(nvim._session, nvim.channel_id, nvim.metadata,
nvim.types, nvim._decode, nvim._err_cb)
def from_session(
cls, session)
Create a new Nvim instance for a Session instance.
This method must be called to create the first Nvim instance, since it queries Nvim metadata for type information and sets a SessionHook for creating specialized objects from Nvim remote handles.
@classmethod
def from_session(cls, session):
"""Create a new Nvim instance for a Session instance.
This method must be called to create the first Nvim instance, since it
queries Nvim metadata for type information and sets a SessionHook for
creating specialized objects from Nvim remote handles.
"""
session.error_wrapper = lambda e: NvimError(e[1])
channel_id, metadata = session.request(b'vim_get_api_info')
if IS_PYTHON3:
# decode all metadata strings for python3
metadata = walk(decode_if_bytes, metadata)
types = {
metadata['types']['Buffer']['id']: Buffer,
metadata['types']['Window']['id']: Window,
metadata['types']['Tabpage']['id']: Tabpage,
}
return cls(session, channel_id, metadata, types)
class NvimError
class NvimError(Exception):
pass
Ancestors (in MRO)
- NvimError
- builtins.Exception
- builtins.BaseException
- builtins.object
Class variables
var args
class Tabpage
A remote Nvim tabpage.
class Tabpage(Remote):
"""A remote Nvim tabpage."""
_api_prefix = "nvim_tabpage_"
def __init__(self, *args):
"""Initialize from session and code_data immutable object.
The `code_data` contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
"""
super(Tabpage, self).__init__(*args)
self.windows = RemoteSequence(self, 'nvim_tabpage_list_wins')
@property
def window(self):
"""Get the `Window` currently focused on the tabpage."""
return self.request('nvim_tabpage_get_win')
@property
def valid(self):
"""Return True if the tabpage still exists."""
return self.request('nvim_tabpage_is_valid')
@property
def number(self):
"""Get the tabpage number."""
return self.request('nvim_tabpage_get_number')
Ancestors (in MRO)
- Tabpage
- neovim.api.common.Remote
- builtins.object
Static methods
def __init__(
self, *args)
Initialize from session and code_data immutable object.
The code_data
contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
def __init__(self, *args):
"""Initialize from session and code_data immutable object.
The `code_data` contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
"""
super(Tabpage, self).__init__(*args)
self.windows = RemoteSequence(self, 'nvim_tabpage_list_wins')
def request(
self, name, *args, **kwargs)
Wrapper for nvim.request.
def request(self, name, *args, **kwargs):
"""Wrapper for nvim.request."""
return self._session.request(name, self, *args, **kwargs)
Instance variables
var number
Get the tabpage number.
var valid
Return True if the tabpage still exists.
var window
Get the Window
currently focused on the tabpage.
var windows
class Window
A remote Nvim window.
class Window(Remote):
"""A remote Nvim window."""
_api_prefix = "nvim_win_"
@property
def buffer(self):
"""Get the `Buffer` currently being displayed by the window."""
return self.request('nvim_win_get_buf')
@property
def cursor(self):
"""Get the (row, col) tuple with the current cursor position."""
return self.request('nvim_win_get_cursor')
@cursor.setter
def cursor(self, pos):
"""Set the (row, col) tuple as the new cursor position."""
return self.request('nvim_win_set_cursor', pos)
@property
def height(self):
"""Get the window height in rows."""
return self.request('nvim_win_get_height')
@height.setter
def height(self, height):
"""Set the window height in rows."""
return self.request('nvim_win_set_height', height)
@property
def width(self):
"""Get the window width in rows."""
return self.request('nvim_win_get_width')
@width.setter
def width(self, width):
"""Set the window height in rows."""
return self.request('nvim_win_set_width', width)
@property
def row(self):
"""0-indexed, on-screen window position(row) in display cells."""
return self.request('nvim_win_get_position')[0]
@property
def col(self):
"""0-indexed, on-screen window position(col) in display cells."""
return self.request('nvim_win_get_position')[1]
@property
def tabpage(self):
"""Get the `Tabpage` that contains the window."""
return self.request('nvim_win_get_tabpage')
@property
def valid(self):
"""Return True if the window still exists."""
return self.request('nvim_win_is_valid')
@property
def number(self):
"""Get the window number."""
return self.request('nvim_win_get_number')
Ancestors (in MRO)
- Window
- neovim.api.common.Remote
- builtins.object
Static methods
def __init__(
self, session, code_data)
Initialize from session and code_data immutable object.
The code_data
contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
def __init__(self, session, code_data):
"""Initialize from session and code_data immutable object.
The `code_data` contains serialization information required for
msgpack-rpc calls. It must be immutable for Buffer equality to work.
"""
self._session = session
self.code_data = code_data
self.handle = unpackb(code_data[1])
self.api = RemoteApi(self, self._api_prefix)
self.vars = RemoteMap(self, self._api_prefix + 'get_var',
self._api_prefix + 'set_var')
self.options = RemoteMap(self, self._api_prefix + 'get_option',
self._api_prefix + 'set_option')
def request(
self, name, *args, **kwargs)
Wrapper for nvim.request.
def request(self, name, *args, **kwargs):
"""Wrapper for nvim.request."""
return self._session.request(name, self, *args, **kwargs)
Instance variables
var buffer
Get the Buffer
currently being displayed by the window.
var col
0-indexed, on-screen window position(col) in display cells.
var cursor
Get the (row, col) tuple with the current cursor position.
var height
Get the window height in rows.
var number
Get the window number.
var row
0-indexed, on-screen window position(row) in display cells.
var tabpage
Get the Tabpage
that contains the window.
var valid
Return True if the window still exists.
var width
Get the window width in rows.
Sub-modules
API for working with a Nvim Buffer.
Code shared between the API classes.
Main Nvim interface.
API for working with Nvim tabpages.
API for working with Nvim windows.