Skip to content

Commit

Permalink
implement update_highlights using lua
Browse files Browse the repository at this point in the history
  • Loading branch information
bfredl committed Apr 25, 2018
1 parent 1877be8 commit f07190a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
23 changes: 23 additions & 0 deletions neovim/api/buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,29 @@ def clear_highlight(self, src_id, line_start=0, line_end=-1, async_=None,
self.request('nvim_buf_clear_highlight', src_id,
line_start, line_end, async_=async_)

def update_highlights(self, src_id, hls, clear_start=0, clear_end=-1,
clear=False, async_=True):
"""Add or update highlights in batch to avoid unnecessary redraws.
A `src_id` must have been allocated prior to use of this function. Use
for instance `nvim.new_highlight_source()` to get a src_id for your
plugin.
`hls` should be a list of highlight items. Each item should be a list
or tuple on the form `("GroupName", linenr, col_start, col_end)` or
`("GroupName", linenr)` to highlight an entire line.
By default existing highlights are preserved. Specify a line range with
clear_start and clear_end to replace highlights in this range. As a
shorthand, use clear=True to clear the entire buffer before adding the
new highlights.
"""
if clear and clear_start is None:
clear_start = 0
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 Down
29 changes: 29 additions & 0 deletions neovim/api/nvim.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,29 @@

os_chdir = os.chdir

lua_module = """
local a = vim.api
local function update_highlights(buf, src_id, hls, clear_first, clear_end)
if clear_first ~= nil then
a.nvim_buf_clear_highlight(buf, src_id, clear_first, clear_end)
end
for _,hl in pairs(hls) do
local group, line, col_start, col_end = unpack(hl)
if col_start == nil then
col_start = 0
end
if col_end == nil then
col_end = -1
end
a.nvim_buf_add_highlight(buf, src_id, group, line, col_start, col_end)
end
end
local chid = ...
local mod = {update_highlights=update_highlights}
_G["_pynvim_"..chid] = mod
"""


class Nvim(object):

Expand Down Expand Up @@ -116,6 +139,12 @@ def _to_nvim(self, obj):
return ExtType(*obj.code_data)
return obj

def _get_lua_private(self):
if not getattr(self._session, "_has_lua", False):
self.exec_lua(lua_module, self.channel_id)
self._session._has_lua = True
return getattr(self.lua, "_pynvim_{}".format(self.channel_id))

def request(self, name, *args, **kwargs):
r"""Send an API request or notification to nvim.
Expand Down
2 changes: 1 addition & 1 deletion neovim/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def find_module(fullname, path):


def check_async(async_, kwargs, default):
"""Return a value of 'async' in kwargs or default when async_ is None
"""Return a value of 'async' in kwargs or default when async_ is None.
This helper function exists for backward compatibility (See #274).
It shows a warning message when 'async' in kwargs is used to note users.
Expand Down
8 changes: 8 additions & 0 deletions test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,11 @@ def test_set_items_for_range():
r = vim.current.buffer.range(1, 3)
r[1:3] = ['foo']*3
eq(vim.current.buffer[:], ['a', 'foo', 'foo', 'foo', 'd', 'e'])

# NB: we can't easily test the effect of this. But at least run the lua
# function sync, so we know it runs without runtime error with simple args.
@with_setup(setup=cleanup)
def test_update_highlights():
vim.current.buffer[:] = ['a', 'b', 'c']
src_id = vim.new_highlight_source()
vim.current.buffer.update_highlights(src_id, [["Comment", 0, 0, -1], ("String", 1, 0, 1)], clear=True, async_=False)

0 comments on commit f07190a

Please sign in to comment.