Skip to content

Commit 2c0880e

Browse files
committed
implement update_highlights using lua
1 parent 2d8889d commit 2c0880e

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

neovim/api/buffer.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,29 @@ def clear_highlight(self, src_id, line_start=0, line_end=-1, async_=None,
112112
self.request('nvim_buf_clear_highlight', src_id,
113113
line_start, line_end, async_=async_)
114114

115+
def update_highlights(self, src_id, hls, clear_start=0, clear_end=-1,
116+
clear=False, async_=True):
117+
"""Add or update highlights in batch to avoid unnecessary redraws.
118+
119+
A `src_id` must have been allocated prior to use of this function. Use
120+
for instance `nvim.new_highlight_source()` to get a src_id for your
121+
plugin.
122+
123+
`hls` should be a list of highlight items. Each item should be a list
124+
or tuple on the form `("GroupName", linenr, col_start, col_end)` or
125+
`("GroupName", linenr)` to highlight an entire line.
126+
127+
By default existing highlights are preserved. Specify a line range with
128+
clear_start and clear_end to replace highlights in this range. As a
129+
shorthand, use clear=True to clear the entire buffer before adding the
130+
new highlights.
131+
"""
132+
if clear and clear_start is None:
133+
clear_start = 0
134+
lua = self._session._get_lua_private()
135+
lua.update_highlights(self, src_id, hls, clear_start, clear_end,
136+
async_=async_)
137+
115138
@property
116139
def name(self):
117140
"""Get the buffer name."""

neovim/api/nvim.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,29 @@
1919

2020
os_chdir = os.chdir
2121

22+
lua_module = """
23+
local a = vim.api
24+
local function update_highlights(buf, src_id, hls, clear_first, clear_end)
25+
if clear_first ~= nil then
26+
a.nvim_buf_clear_highlight(buf, src_id, clear_first, clear_end)
27+
end
28+
for _,hl in pairs(hls) do
29+
local group, line, col_start, col_end = unpack(hl)
30+
if col_start == nil then
31+
col_start = 0
32+
end
33+
if col_end == nil then
34+
col_end = -1
35+
end
36+
a.nvim_buf_add_highlight(buf, src_id, group, line, col_start, col_end)
37+
end
38+
end
39+
40+
local chid = ...
41+
local mod = {update_highlights=update_highlights}
42+
_G["_pynvim_"..chid] = mod
43+
"""
44+
2245

2346
class Nvim(object):
2447

@@ -116,6 +139,12 @@ def _to_nvim(self, obj):
116139
return ExtType(*obj.code_data)
117140
return obj
118141

142+
def _get_lua_private(self):
143+
if not getattr(self._session, "_has_lua", False):
144+
self.exec_lua(lua_module, self.channel_id)
145+
self._session._has_lua = True
146+
return getattr(self.lua, "_pynvim_{}".format(self.channel_id))
147+
119148
def request(self, name, *args, **kwargs):
120149
r"""Send an API request or notification to nvim.
121150

neovim/compat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def find_module(fullname, path):
4040

4141

4242
def check_async(async_, kwargs, default):
43-
"""Return a value of 'async' in kwargs or default when async_ is None
43+
"""Return a value of 'async' in kwargs or default when async_ is None.
4444
4545
This helper function exists for backward compatibility (See #274).
4646
It shows a warning message when 'async' in kwargs is used to note users.

test/test_buffer.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,10 @@ def test_set_items_for_range(vim):
161161
r = vim.current.buffer.range(1, 3)
162162
r[1:3] = ['foo']*3
163163
assert vim.current.buffer[:] == ['a', 'foo', 'foo', 'foo', 'd', 'e']
164+
165+
# NB: we can't easily test the effect of this. But at least run the lua
166+
# function sync, so we know it runs without runtime error with simple args.
167+
def test_update_highlights(vim):
168+
vim.current.buffer[:] = ['a', 'b', 'c']
169+
src_id = vim.new_highlight_source()
170+
vim.current.buffer.update_highlights(src_id, [["Comment", 0, 0, -1], ("String", 1, 0, 1)], clear=True, async_=False)

0 commit comments

Comments
 (0)