Skip to content

Commit a437f97

Browse files
committed
update documentation (use links in README, lua, note about __init__)
1 parent eeebcb2 commit a437f97

File tree

4 files changed

+107
-156
lines changed

4 files changed

+107
-156
lines changed

README.md

+18-135
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
### Python client to [Neovim](https://github.com/neovim/neovim)
1+
### Pynvim: Python client to [Neovim](https://github.com/neovim/neovim)
22

33
[![Build Status](https://travis-ci.org/neovim/python-client.svg?branch=master)](https://travis-ci.org/neovim/python-client)
4+
[![Documentation Status](https://readthedocs.org/projects/pynvim/badge/?version=latest)](http://pynvim.readthedocs.io/en/latest/?badge=latest)
45
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/neovim/python-client/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/neovim/python-client/?branch=master)
56
[![Code Coverage](https://scrutinizer-ci.com/g/neovim/python-client/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/neovim/python-client/?branch=master)
67

7-
Implements support for python plugins in Nvim. Also works as a library for
8+
Pynvim implements support for python plugins in Nvim. It also works as a library for
89
connecting to and scripting Nvim processes through its msgpack-rpc API.
910

1011
#### Installation
@@ -36,96 +37,23 @@ pip3 install .
3637

3738
#### Python Plugin API
3839

39-
Neovim has a new mechanism for defining plugins, as well as a number of
40-
extensions to the python API. The API extensions are accessible no matter if the
41-
traditional `:python` interface or the new mechanism is used, as discussed
42-
below.
43-
44-
* `vim.funcs` exposes vimscript functions (both builtin and global user defined
45-
functions) as a python namespace. For instance to set the value of a register
46-
```
47-
vim.funcs.setreg('0', ["some", "text"], 'l')
48-
```
49-
50-
* `vim.api` exposes nvim API methods. For instance to call `nvim_strwidth`,
51-
```
52-
result = vim.api.strwidth("some text")
53-
```
54-
Note the initial `nvim_` is not included. Also, object methods can be called
55-
directly on their object,
56-
```
57-
buf = vim.current.buffer
58-
len = buf.api.line_count()
59-
```
60-
calls `nvim_buf_line_count`. Alternatively msgpack requests can be invoked
61-
directly,
62-
```
63-
result = vim.request("nvim_strwith", "some text")
64-
len = vim.request("nvim_buf_line_count", buf)
65-
```
66-
67-
* The API is not thread-safe in general. However, `vim.async_call` allows a
68-
spawned thread to schedule code to be executed on the main thread. This method
69-
could also be called from `:python` or a synchronous request handler, to defer
70-
some execution that shouldn't block nvim.
71-
```
72-
:python vim.async_call(myfunc, args...)
73-
74-
```
75-
Note that this code will still block the plugin host if it does long-running
76-
computations. Intensive computations should be done in a separate thread (or
77-
process), and `vim.async_call` can be used to send results back to nvim.
78-
79-
* Some methods accept an `async_` keyword argument: `vim.eval`, `vim.command`,
80-
`vim.request` as well as the `vim.funcs` and `vim.api` wrappers. When
81-
`async_=True` is passed the client will not wait for nvim to complete the
82-
request (which also means that the return value is unavailable).
83-
84-
#### Remote (new-style) plugins
85-
86-
Neovim allows python3 plugins to be defined by placing python files or packages
87-
in `rplugin/python3/` (in a runtimepath folder). Python2 rplugins are also
88-
supported and placed in `rplugin/python/`, but are considered deprecated.
89-
Further added library features will only be available on python3. Rplugins follow
90-
the structure of this example:
40+
Pynvim supports python _remote plugins_ (via the language-agnostic Nvim rplugin
41+
interface), as well as _Vim plugins_ (via the `:python[3]` interface). Thus when
42+
pynvim is installed Neovim will report support for the `+python[3]` Vim feature.
9143

92-
```python
93-
import neovim
94-
95-
@neovim.plugin
96-
class TestPlugin(object):
97-
98-
def __init__(self, nvim):
99-
self.nvim = nvim
100-
101-
@neovim.function("TestFunction", sync=True)
102-
def testfunction(self, args):
103-
return 3
104-
105-
@neovim.command("TestCommand", range='', nargs='*')
106-
def testcommand(self, args, range):
107-
self.nvim.current.line = ('Command with args: {}, range: {}'
108-
.format(args, range))
109-
110-
@neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")', sync=True)
111-
def on_bufenter(self, filename):
112-
self.nvim.out_write("testplugin is in " + filename + "\n")
113-
```
44+
The rplugin interface allows plugins to handle vimL function calls as well as
45+
defining commands and autocommands, and such plugins can operate asynchronously
46+
without blocking nvim. For details on the new rplugin interface,
47+
see the [Remote Plugin](http://pynvim.readthedocs.io/en/latest/usage/remote-plugins.html) documentation.
11448

115-
If `sync=True` is supplied nvim will wait for the handler to finish (this is
116-
required for function return values), but by default handlers are executed
117-
asynchronously.
49+
Pynvim defines some extensions over the vim python API:
11850

119-
Normally async handlers (`sync=False`, the default) are blocked while a
120-
synchronous handler is running. This ensures that async handlers can call
121-
requests without nvim confusing these requests with requests from a synchronous
122-
handler. To execute an asynchronous handler even when other handlers are
123-
running, add `allow_nested=True` to the decorator. The handler must then not
124-
make synchronous nvim requests, but it can make asynchronous requests, i e
125-
passing `async_=True`.
51+
* Builtin and plugin vimL functions are available as `nvim.funcs`
52+
* API functions are available as `vim.api` and for objects such as `buffer.api`
53+
* Lua functions can be defined using `vim.exec_lua` and called with `vim.lua`
54+
* Support for thread-safety and async requests.
12655

127-
You need to run `:UpdateRemotePlugins` in nvim for changes in the specifications
128-
to have effect. For details see `:help remote-plugin` in nvim.
56+
See the [Python Plugin API](http://pynvim.readthedocs.io/en/latest/usage/python-plugin-api.html) documentation for usage of this new functionality.
12957

13058
#### Development
13159

@@ -134,53 +62,8 @@ If you change the code, you need to run
13462
pip2 install .
13563
pip3 install .
13664
```
137-
for the changes to have effect. Alternatively you could execute neovim
138-
with the `$PYTHONPATH` environment variable
139-
```
140-
PYTHONPATH=/path/to/python-client nvim
141-
```
142-
But note this is not completely reliable as installed packages can appear before
143-
`$PYTHONPATH` in the python search path.
144-
145-
You need to rerun this command if you have changed the code, in order for nvim
146-
to use it for the plugin host.
147-
148-
To run the tests execute
149-
150-
```sh
151-
pytest
152-
```
153-
154-
This will run the tests in an embedded instance of nvim.
155-
If you want to test a different version than `nvim` in `$PATH` use
156-
```sh
157-
NVIM_CHILD_ARGV='["/path/to/nvim", "-u", "NONE", "--embed"]' pytest
158-
```
159-
160-
Alternatively, if you want to see the state of nvim, you could use
161-
162-
```sh
163-
export NVIM_LISTEN_ADDRESS=/tmp/nvimtest
164-
xterm -e "nvim -u NONE"&
165-
pytest
166-
```
167-
168-
But note you need to restart nvim every time you run the tests! Substitute your
169-
favorite terminal emulator for `xterm`.
170-
171-
#### Troubleshooting
172-
173-
You can run the plugin host in nvim with logging enabled to debug errors:
174-
```
175-
NVIM_PYTHON_LOG_FILE=logfile NVIM_PYTHON_LOG_LEVEL=DEBUG nvim
176-
```
177-
As more than one python host process might be started, the log filenames take
178-
the pattern `logfile_pyX_KIND` where `X` is the major python version (2 or 3)
179-
and `KIND` is either "rplugin" or "script" (for the `:python[3]`
180-
script interface).
181-
182-
If the host cannot start at all, the error could be found in `~/.nvimlog` if
183-
`nvim` was compiled with logging.
65+
for the changes to have effect. For instructions of testing and troubleshooting,
66+
see the [development](http://pynvim.readthedocs.io/en/latest/development.html) documentation.
18467

18568
#### Usage through the python REPL
18669

docs/development.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ in order for Neovim to use it for the plugin host.
1919

2020
To run the tests execute::
2121

22-
nosetests
22+
pytest
2323

2424
This will run the tests in an embedded instance of Neovim.
2525
If you want to test a different version than ``nvim`` in ``$PATH`` use::
2626

27-
NVIM_CHILD_ARGV='["/path/to/nvim", "-u", "NONE", "--embed"]' nosetests
27+
NVIM_CHILD_ARGV='["/path/to/nvim", "-u", "NONE", "--embed"]' pytest
2828

2929
Alternatively, if you want to see the state of nvim, you could use::
3030

3131
export NVIM_LISTEN_ADDRESS=/tmp/nvimtest
3232
xterm -e "nvim -u NONE"&
33-
nosetests
33+
pytest
3434

3535
But note you need to restart Neovim every time you run the tests!
3636
Substitute your favorite terminal emulator for ``xterm``.

docs/usage/python-plugin-api.rst

+76-17
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,7 @@ as well as a number of extensions to the python API.
66
The API extensions are accessible no matter if the traditional ``:python`` interface or the new mechanism is used,
77
as discussed on :doc:`remote-plugins`.
88

9-
``vim.funcs``
10-
-------------
11-
12-
Exposes vimscript functions (both builtin and global user defined functions) as a python namespace.
13-
For instance to set the value of a register:
14-
15-
.. code-block:: python
16-
17-
vim.funcs.setreg('0', ["some", "text"], 'l')
18-
19-
``vim.api``
9+
Nvim API methods: ``vim.api``
2010
-----------
2111

2212
Exposes Neovim API methods.
@@ -32,15 +22,83 @@ Also, object methods can be called directly on their object:
3222
.. code-block:: python
3323
3424
buf = vim.current.buffer
35-
len = buf.api.line_count()
25+
length = buf.api.line_count()
3626
3727
calls ``nvim_buf_line_count``.
3828
Alternatively msgpack requests can be invoked directly:
3929

4030
.. code-block:: python
4131
4232
result = vim.request("nvim_strwith", "some text")
43-
len = vim.request("nvim_buf_line_count", buf)
33+
length = vim.request("nvim_buf_line_count", buf)
34+
35+
Both ``vim.api`` and ``vim.request`` can take an ``async_=True`` keyword argument
36+
to instead send a msgpack notification. Nvim will execute the API method the
37+
same way, but python will not wait for it to finish, so the return value is
38+
unavailable.
39+
40+
Vimscript functions: ``vim.funcs``
41+
-------------
42+
43+
Exposes vimscript functions (both builtin and global user defined functions) as a python namespace.
44+
For instance to set the value of a register:
45+
46+
.. code-block:: python
47+
48+
vim.funcs.setreg('0', ["some", "text"], 'l')
49+
50+
These functions can also take the ``async_=True`` keyword argument, just like API
51+
methods.
52+
53+
Lua integration
54+
-----------
55+
56+
Python plugins can define and invoke lua code in Nvim's in-process lua
57+
interpreter. This is especially useful in asynchronous contexts, where an async
58+
event handler can schedule a complex operation with many api calls to be
59+
executed by nvim without interleaved processing of user input or other event
60+
sources (unless requested).
61+
62+
The recommended usage is the following pattern. First use ``vim.exec_lua(code)``
63+
to define a module with lua functions:
64+
65+
.. code-block:: python
66+
67+
vim.exec_lua("""
68+
local a = vim.api
69+
local function add(a,b)
70+
return a+b
71+
end
72+
73+
local function buffer_ticks()
74+
local ticks = {}
75+
for _, buf in ipairs(a.nvim_list_bufs()) do
76+
ticks[#ticks+1] = a.nvim_buf_get_changedtick(buf)
77+
end
78+
return ticks
79+
end
80+
81+
_testplugin = {add=add, buffer_ticks=buffer_ticks}
82+
""")
83+
84+
Alternatively, place the code in ``/lua/testplugin.lua`` under your plugin repo
85+
root, and use ``vim.exec_lua("_testplugin = require('testplugin')")``.
86+
In both cases, replace ``testplugin`` with a unique string based on your plugin
87+
name.
88+
89+
Then, the module can be acessed as ``vim.lua._testplugin``.
90+
91+
.. code-block:: python
92+
93+
mod = vim.lua._testplugin
94+
mod.add(2,3) # => 5
95+
mod.buffer_ticks() # => list of ticks
96+
97+
These functions can also take the ``async_=True`` keyword argument, just like API
98+
methods.
99+
100+
It is also possible to pass arguments directly to a code block. Using
101+
``vim.exec_lua(code, args...)``, the arguments will be available in lua as ``...``.
44102

45103
Async calls
46104
-----------
@@ -58,7 +116,8 @@ Note that this code will still block the plugin host if it does long-running com
58116
Intensive computations should be done in a separate thread (or process),
59117
and ``vim.async_call`` can be used to send results back to Neovim.
60118

61-
Some methods accept an ``async_`` keyword argument:
62-
``vim.eval``, ``vim.command``, ``vim.request`` as well as the ``vim.funcs`` and ``vim.api`` wrappers.
63-
When ``async_=True`` is passed the client will not wait for Neovim to complete the request
64-
(which also means that the return value is unavailable).
119+
Some methods accept an ``async_`` keyword argument: ``vim.eval``,
120+
``vim.command``, ``vim.request`` as well as the ``vim.funcs``, ``vim.api` and
121+
``vim.lua``` wrappers. When ``async_=True`` is passed the client will not wait
122+
for Neovim to complete the request (which also means that the return value is
123+
unavailable).

docs/usage/remote-plugins.rst

+10-1
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,18 @@ are blocked while a synchronous handler is running.
4141
This ensures that async handlers can call requests without Neovim confusing these requests with requests from a synchronous handler.
4242
To execute an asynchronous handler even when other handlers are running,
4343
add ``allow_nested=True`` to the decorator.
44-
The handler must then not make synchronous Neovim requests,
44+
This handler must then not make synchronous Neovim requests,
4545
but it can make asynchronous requests, i.e. passing ``async_=True``.
4646

47+
.. note::
48+
49+
Plugins must not invoke API methods in ``__init__`` or global module scope
50+
(or really do anything with non-trivial side-effects). A well-behaved rplugin
51+
will not start executing until its functionality is requested by the user.
52+
Initialize the plugin the first time the user invokes a command, or use an
53+
appropriate autocommand, if it e.g. makes sense to automatically start the
54+
plugin for a given filetype.
55+
4756
You need to run ``:UpdateRemotePlugins`` in Neovim for changes in the specifications to have effect.
4857
For details see ``:help remote-plugin`` in Neovim.
4958

0 commit comments

Comments
 (0)