19
19
20
20
os_chdir = os .chdir
21
21
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
+
22
45
23
46
class Nvim (object ):
24
47
@@ -92,6 +115,7 @@ def __init__(self, session, channel_id, metadata, types,
92
115
self .current = Current (self )
93
116
self .session = CompatibilitySession (self )
94
117
self .funcs = Funcs (self )
118
+ self .lua = LuaFuncs (self )
95
119
self .error = NvimError
96
120
self ._decode = decode
97
121
self ._err_cb = err_cb
@@ -115,6 +139,12 @@ def _to_nvim(self, obj):
115
139
return ExtType (* obj .code_data )
116
140
return obj
117
141
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
+
118
148
def request (self , name , * args , ** kwargs ):
119
149
r"""Send an API request or notification to nvim.
120
150
@@ -253,6 +283,27 @@ def call(self, name, *args, **kwargs):
253
283
"""Call a vimscript function."""
254
284
return self .request ('nvim_call_function' , name , args , ** kwargs )
255
285
286
+ def exec_lua (self , code , * args , ** kwargs ):
287
+ """Execute lua code.
288
+
289
+ Additional parameters are available as `...` inside the lua chunk.
290
+ Only statements are executed. To evaluate an expression, prefix it
291
+ with `return`: `return my_function(...)`
292
+
293
+ There is a shorthand syntax to call lua functions with arguments:
294
+
295
+ nvim.lua.func(1,2)
296
+ nvim.lua.mymod.myfunction(data, async_=True)
297
+
298
+ is equivalent to
299
+
300
+ nvim.exec_lua("return func(...)", 1, 2)
301
+ nvim.exec_lua("mymod.myfunction(...)", data, async_=True)
302
+
303
+ Note that with `async_=True` there is no return value.
304
+ """
305
+ return self .request ('nvim_execute_lua' , code , args , ** kwargs )
306
+
256
307
def strwidth (self , string ):
257
308
"""Return the number of display cells `string` occupies.
258
309
@@ -467,5 +518,29 @@ def __getattr__(self, name):
467
518
return partial (self ._nvim .call , name )
468
519
469
520
521
+ class LuaFuncs (object ):
522
+
523
+ """Wrapper to allow lua functions to be called like python methods."""
524
+
525
+ def __init__ (self , nvim , name = "" ):
526
+ self ._nvim = nvim
527
+ self .name = name
528
+
529
+ def __getattr__ (self , name ):
530
+ """Return wrapper to named api method."""
531
+ prefix = self .name + "." if self .name else ""
532
+ return LuaFuncs (self ._nvim , prefix + name )
533
+
534
+ def __call__ (self , * args , ** kwargs ):
535
+ # first new function after keyword rename, be a bit noisy
536
+ if 'async' in kwargs :
537
+ raise ValueError ('"async" argument is not allowed. '
538
+ 'Use "async_" instead.' )
539
+ async_ = kwargs .get ('async_' , False )
540
+ pattern = "return {}(...)" if not async_ else "{}(...)"
541
+ code = pattern .format (self .name )
542
+ return self ._nvim .exec_lua (code , * args , ** kwargs )
543
+
544
+
470
545
class NvimError (Exception ):
471
546
pass
0 commit comments