From 2dc54d027f9e17c30052a1af966150f767293843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Linse?= Date: Fri, 8 Jun 2018 13:34:18 +0200 Subject: [PATCH] buffer: support attachment in hosted plugins --- neovim/api/buffer.py | 27 ++++++++++++++++++++++++++- neovim/plugin/host.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/neovim/api/buffer.py b/neovim/api/buffer.py index 786e322c..e12e9c69 100644 --- a/neovim/api/buffer.py +++ b/neovim/api/buffer.py @@ -134,7 +134,6 @@ def update_highlights(self, src_id, hls, clear_start=0, clear_end=-1, lua = self._session._get_lua_private() lua.update_highlights(self, src_id, hls, clear_start, clear_end, async_=async_) - @property def name(self): """Get the buffer name.""" @@ -155,6 +154,32 @@ def number(self): """Get the buffer number.""" return self.handle + def attach(self, cb): + sess = self._session._session + if self.handle not in sess.attached_buffers: + a = BufAttachState() + sess.attached_buffers[self.handle] = a + a.callbacks.append(cb) + self.api.attach(True, {}) + else: + a = sess.attached_buffers[self.handle] + a.callbacks.append(cb) + cb(self, a.changedtick, a.lines) + + def detach(): + for i in range(len(a.callbacks)): + if a.callbacks[i] is cb: + del a.callbacks[i] + return + else: + raise ValueError("callback already detached") + + return detach + +class BufAttachState(object): + def __init__(self): + self.callbacks = [] + self.lines = [] class Range(object): def __init__(self, buffer, start, end): diff --git a/neovim/plugin/host.py b/neovim/plugin/host.py index 81dd551a..4c8aea6b 100644 --- a/neovim/plugin/host.py +++ b/neovim/plugin/host.py @@ -32,10 +32,17 @@ class Host(object): def __init__(self, nvim): """Set handlers for plugin_load/plugin_unload.""" self.nvim = nvim + self.nvim._session.attached_buffers = {} + # TODO: delet this + self.nvim._session.elog = [] self._specs = {} self._loaded = {} self._load_errors = {} - self._notification_handlers = {} + self._notification_handlers = { + 'nvim_buf_lines_event': self._on_buf_lines, + 'nvim_buf_changedtick_event': self._on_buf_changedtick, + 'nvim_buf_detach_event': self._on_buf_detach, + } self._request_handlers = { 'poll': lambda: 'ok', 'specs': self._on_specs_request, @@ -96,6 +103,7 @@ def _on_notification(self, name, args): """Handle a msgpack-rpc notification.""" if IS_PYTHON3: name = decode_if_bytes(name) + self.nvim._session.elog.append([name]+args) handler = self._notification_handlers.get(name, None) if not handler: msg = self._missing_handler_error(name, 'notification') @@ -220,3 +228,22 @@ def _configure_nvim_for(self, obj): if decode: nvim = nvim.with_decode(decode) return nvim + + def _on_buf_lines(self, buf, changedtick, first, last, data, more): + a = self.nvim._session.attached_buffers[buf.handle] + a.lines[first:last] = data + a.changedtick = changedtick + if more: return + for cb in a.callbacks: + cb(buf, changedtick, a.lines) + + def _on_buf_changedtick(self, buf, changedtick): + a = self.nvim._session.attached_buffers[buf.handle] + a.changedtick = changedtick + for cb in a.callbacks: + cb(buf, changedtick, a.lines) + + def _on_buf_detach(self, buf, changedtick, first, last, data, more): + del self.nvim._session.attached_buffers[buf.handle] + for cb in a.callbacks: + cb(buf, -1, None)