Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] buffer: support attachment in hosted plugins #340

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 26 additions & 1 deletion neovim/api/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB: should detach when callbacks goes to zero.

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):
Expand Down
29 changes: 28 additions & 1 deletion neovim/plugin/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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)