Skip to content

Commit

Permalink
rplugin: conditionally enable nested notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
bfredl committed Nov 8, 2017
1 parent 562eac9 commit 786c581
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 19 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ below.
process), and `vim.async_call` can be used to send results back to nvim.

* Some methods accept an extra keyword-only argument `async`: `vim.eval`,
`vim.command` as well as the `vim.funcs` wrappers. The python host will not
wait for nvim to complete the request, which also means that the return value
is unavailable.
`vim.command` as well as the `vim.funcs` wrappers. When `async=True` is
passed, the python host will not wait for nvim to complete the request, which
also means that the return value is unavailable.

#### Remote (new-style) plugins

Expand Down Expand Up @@ -96,6 +96,14 @@ If `sync=True` is supplied nvim will wait for the handler to finish (this is
required for function return values), but by default handlers are executed
asynchronously.

Normally async handlers (`sync=False`, the default) are blocked while a
synchronous handler is running. This ensures that async handlers can call
requests without nvim confusing these requests with requests from a synchronous
handler. To execute an asynchronous handler even when other handlers are
running, add `allow_nested=True` to the decorator. The handler must then not
make synchronous nvim requests, but it can make asynchronous requests, i e
passing `async=True`.

You need to run `:UpdateRemotePlugins` in nvim for changes in the specifications
to have effect. For details see `:help remote-plugin` in nvim.

Expand Down
10 changes: 5 additions & 5 deletions neovim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ def setup_logging(name):
logging.root.addHandler(handler)
level = logging.INFO
if 'NVIM_PYTHON_LOG_LEVEL' in os.environ:
l = getattr(logging,
os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(),
level)
if isinstance(l, int):
level = l
lvl = getattr(logging,
os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(),
level)
if isinstance(lvl, int):
level = lvl
logger.setLevel(level)


Expand Down
4 changes: 2 additions & 2 deletions neovim/api/nvim.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ def replace_termcodes(self, string, from_part=False, do_lt=True,
return self.request('vim_replace_termcodes', string,
from_part, do_lt, special)

def out_write(self, msg):
def out_write(self, msg, **kwargs):
"""Print `msg` as a normal message."""
return self.request('nvim_out_write', msg)
return self.request('nvim_out_write', msg, **kwargs)

def err_write(self, msg, **kwargs):
"""Print `msg` as an error message."""
Expand Down
27 changes: 21 additions & 6 deletions neovim/plugin/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def dec(f):


def command(name, nargs=0, complete=None, range=None, count=None, bang=False,
register=False, sync=False, eval=None):
register=False, sync=False, allow_nested=False, eval=None):
"""Tag a function or plugin method as a Nvim command handler."""
def dec(f):
f._nvim_rpc_method_name = 'command:{}'.format(name)
Expand Down Expand Up @@ -73,17 +73,22 @@ def dec(f):
if eval:
opts['eval'] = eval

if not sync and allow_nested:
rpc_sync = "urgent"
else:
rpc_sync = sync

f._nvim_rpc_spec = {
'type': 'command',
'name': name,
'sync': sync,
'sync': rpc_sync,
'opts': opts
}
return f
return dec


def autocmd(name, pattern='*', sync=False, eval=None):
def autocmd(name, pattern='*', sync=False, allow_nested=False, eval=None):
"""Tag a function or plugin method as a Nvim autocommand handler."""
def dec(f):
f._nvim_rpc_method_name = 'autocmd:{}:{}'.format(name, pattern)
Expand All @@ -98,17 +103,22 @@ def dec(f):
if eval:
opts['eval'] = eval

if not sync and allow_nested:
rpc_sync = "urgent"
else:
rpc_sync = sync

f._nvim_rpc_spec = {
'type': 'autocmd',
'name': name,
'sync': sync,
'sync': rpc_sync,
'opts': opts
}
return f
return dec


def function(name, range=False, sync=False, eval=None):
def function(name, range=False, sync=False, allow_nested=False, eval=None):
"""Tag a function or plugin method as a Nvim function handler."""
def dec(f):
f._nvim_rpc_method_name = 'function:{}'.format(name)
Expand All @@ -124,10 +134,15 @@ def dec(f):
if eval:
opts['eval'] = eval

if not sync and allow_nested:
rpc_sync = "urgent"
else:
rpc_sync = sync

f._nvim_rpc_spec = {
'type': 'function',
'name': name,
'sync': sync,
'sync': rpc_sync,
'opts': opts
}
return f
Expand Down
6 changes: 3 additions & 3 deletions neovim/plugin/host.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""Implements a Nvim host for python plugins."""
import functools
import imp
import inspect
import logging
import os
import os.path
import re

from functools import partial
from traceback import format_exc

from . import script_host
Expand Down Expand Up @@ -181,8 +181,8 @@ def predicate(o):
if fn._nvim_prefix_plugin_path:
method = '{}:{}'.format(plugin_path, method)

fn_wrapped = functools.partial(self._wrap_function, fn,
sync, decode, nvim_bind, method)
fn_wrapped = partial(self._wrap_function, fn,
sync, decode, nvim_bind, method)
self._copy_attributes(fn, fn_wrapped)
# register in the rpc handler dict
if sync:
Expand Down

0 comments on commit 786c581

Please sign in to comment.