Skip to content

Commit

Permalink
vim.buffers is a map not a list.
Browse files Browse the repository at this point in the history
python-buffers describes vim.buffers as a mapping object. python-buffer
documents that b.number where b is a Buffer object can be used as a
python-buffers key. I.e. b == vim.buffers[b.number] should be true if b
is a valid buffer object.

nvim.py was implementing vim.buffers as a RemoteSequence which doesn't
provide the aforementioned properties. This change implements it as a
Buffer object instead. The latter is a new class that implements the
hybrid sequence/map interface that python-buffers describes.
  • Loading branch information
asankah committed Jun 8, 2016
1 parent e58cd58 commit 8eb6ba7
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ bridge](http://vimdoc.sourceforge.net/htmldoc/if_pyth.html#python-vim)):
# Create a python API session attached to unix domain socket created above:
>>> nvim = attach('socket', path='/tmp/nvim')
# Now do some work.
>>> buffer = nvim.buffers[0] # Get the first buffer
>>> buffer = nvim.current.buffer # Get the current buffer
>>> buffer[0] = 'replace first line'
>>> buffer[:] = ['replace whole buffer']
>>> nvim.command('vsplit')
Expand Down
2 changes: 1 addition & 1 deletion neovim/api/buffer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""API for working with Nvim buffers."""
"""API for working with a Nvim Buffer."""
from .common import Remote
from ..compat import IS_PYTHON3

Expand Down
6 changes: 3 additions & 3 deletions neovim/api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ class RemoteSequence(object):
sequences(of lines, buffers, windows and tabpages) with an API that
is similar to the one provided by the python-vim interface.
For example, the 'buffers' property of the `Nvim class is a RemoteSequence
sequence instance, and the expression `nvim.buffers[0]` is translated to
session.request('vim_get_buffers')[0].
For example, the 'windows' property of the `Nvim` class is a RemoteSequence
sequence instance, and the expression `nvim.windows[0]` is translated to
session.request('vim_get_windows')[0].
It can also receive an optional self_obj that will be passed as first
argument of the request. For example, `tabpage.windows[0]` is translated
Expand Down
37 changes: 36 additions & 1 deletion neovim/api/nvim.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def __init__(self, session, channel_id, metadata, types,
self.vars = RemoteMap(self, 'vim_get_var', 'vim_set_var')
self.vvars = RemoteMap(self, 'vim_get_vvar', None)
self.options = RemoteMap(self, 'vim_get_option', 'vim_set_option')
self.buffers = RemoteSequence(self, 'vim_get_buffers')
self.buffers = Buffers(self)
self.windows = RemoteSequence(self, 'vim_get_windows')
self.tabpages = RemoteSequence(self, 'vim_get_tabpages')
self.current = Current(self)
Expand Down Expand Up @@ -331,6 +331,41 @@ def handler():
self._session.threadsafe_call(handler)


class Buffers(object):

"""Remote NVim buffers.
Currently the interface for interacting with remote NVim buffers is the
`vim_get_buffers` msgpack-rpc function. Most methods fetch the list of
buffers from NVim.
Conforms to *python-buffers*.
"""

def __init__(self, nvim):
"""Initialize a Buffers object with Nvim object `nvim`."""
self._fetch_buffers = nvim.api.get_buffers

def __len__(self):
"""Return the count of buffers."""
return len(self._fetch_buffers())

def __getitem__(self, number):
"""Return the Buffer object matching buffer number `number`."""
for b in self._fetch_buffers():
if b.number == number:
return b
raise KeyError(number)

def __contains__(self, b):
"""Return whether Buffer `b` is a known valid buffer."""
return isinstance(b, Buffer) and b.valid

def __iter__(self):
"""Return an iterator over the list of buffers."""
return iter(self._fetch_buffers())


class CompatibilitySession(object):

"""Helper class for API compatibility."""
Expand Down
24 changes: 20 additions & 4 deletions test/test_vim.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,29 @@ def test_options():

@with_setup(setup=cleanup)
def test_buffers():
buffers = []

# Number of elements
eq(len(vim.buffers), 1)
eq(vim.buffers[0], vim.current.buffer)

# Indexing (by buffer number)
eq(vim.buffers[vim.current.buffer.number], vim.current.buffer)

buffers.append(vim.current.buffer)
vim.command('new')
eq(len(vim.buffers), 2)
eq(vim.buffers[1], vim.current.buffer)
vim.current.buffer = vim.buffers[0]
eq(vim.buffers[0], vim.current.buffer)
buffers.append(vim.current.buffer)
eq(vim.buffers[vim.current.buffer.number], vim.current.buffer)
vim.current.buffer = buffers[0]
eq(vim.buffers[vim.current.buffer.number], buffers[0])

# Membership test
ok(buffers[0] in vim.buffers)
ok(buffers[1] in vim.buffers)
ok({} not in vim.buffers)

# Iteration
eq(buffers, list(vim.buffers))


@with_setup(setup=cleanup)
Expand Down

0 comments on commit 8eb6ba7

Please sign in to comment.