Hello community, here is the log from the commit of package python-neovim for openSUSE:Factory checked in at 2018-04-17 11:19:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-neovim (Old) and /work/SRC/openSUSE:Factory/.python-neovim.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-neovim" Tue Apr 17 11:19:31 2018 rev:10 rq:597250 version:0.2.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-neovim/python-neovim.changes 2017-11-18 00:20:38.596534910 +0100 +++ /work/SRC/openSUSE:Factory/.python-neovim.new/python-neovim.changes 2018-04-17 11:19:34.528623315 +0200 @@ -1,0 +2,50 @@ +Mon Mar 26 15:33:14 UTC 2018 - roni...@gmail.com + +- Run spec-cleaner. +- Version bump to 0.2.4. + Upstream changelog: + + Version 0.2.4 + + Temporarily disable asyncio on windows again, as stdio is not + functional with asyncio yet. + + The new nvim.loop attribute is for the moment only available on + POSIX systems. + + Version 0.2.3 + + In this release support of python3.3 is dropped. Henceforth we + want python3 rplugins to be able to assume the usage of + asyncio, so they can use the asyncio event loop and libraries + that build on it. + + Furthermore, a close() method is added on nvim session objects. + When used as a library for externally connecting to a nvim + instance (i e not rplugins), it is recommended to call the + close() method on the session object when it is not needed + anymore. Alternatively, sessions can be used as a context + manager: + + with neovim.attach('socket', path=thepath) as nvim: + # do stuff with nvim session in this block: + print(nvim.funcs.getpid()) + print(nvim.current.line) + + * 2689ddc add tests for plugin decorators #298 + * 63f257f allow library users to properly cleanup the event + loop #303 + * 59c184f expose the asyncio event loop as nvim.loop (python + 3.4+ only) #294 + + Version 0.2.1 + + Adds compability with msgpack 0.5.2. + + * e800c64 discover_runtime_directories refactor (#287) + * 9cf971f Travis lint refactor (#288) + * 93e6b5b msgpack-python was renamed to msgpack (#293) + * 6fc0343 fix for msgpack 0.5.2 (#301) + + +------------------------------------------------------------------- Old: ---- python-client-0.2.0.tar.gz New: ---- python-client-0.2.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-neovim.spec ++++++ --- /var/tmp/diff_new_pack.fnAm0R/_old 2018-04-17 11:19:35.876560137 +0200 +++ /var/tmp/diff_new_pack.fnAm0R/_new 2018-04-17 11:19:35.880559950 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-neovim # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,9 +18,10 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-neovim -Version: 0.2.0 +Version: 0.2.4 Release: 0 Summary: Python 2 client to Neovim +# FIXME: use correct group, see "https://en.opensuse.org/openSUSE:Package_group_guidelines" License: Apache-2.0 Group: Productivity/Editors/Vi Url: https://github.com/neovim/python-client @@ -29,7 +30,7 @@ BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros -Requires: neovim >= 0.1.6 +Requires: neovim >= 0.2.1 Requires: python-greenlet Requires: python-msgpack-python BuildArch: noarch @@ -52,7 +53,8 @@ %python_expand %fdupes %{buildroot}%{$python_sitelib} %files %{python_files} -%doc README.md LICENSE +%license LICENSE +%doc README.md %{python_sitelib}/neovim/ %{python_sitelib}/neovim-%{version}-*.egg-info/ ++++++ python-client-0.2.0.tar.gz -> python-client-0.2.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/.gitignore new/python-client-0.2.4/.gitignore --- old/python-client-0.2.0/.gitignore 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/.gitignore 2018-03-06 17:22:22.000000000 +0100 @@ -8,3 +8,6 @@ .cache .eggs .tox + +# Sphinx documentation +docs/_build/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/.readthedocs.yml new/python-client-0.2.4/.readthedocs.yml --- old/python-client-0.2.0/.readthedocs.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/.readthedocs.yml 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,6 @@ +build: + image: latest + +python: + version: 3.6 + setup_py_install: true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/.travis.yml new/python-client-0.2.4/.travis.yml --- old/python-client-0.2.0/.travis.yml 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/.travis.yml 2018-03-06 17:22:22.000000000 +0100 @@ -11,12 +11,11 @@ matrix: include: - python: 3.6 - env: CI_TARGET=flake + env: CI_TARGET=checkqa TOXENV=checkqa python: # If the build matrix gets bigger, also update the number of runs # at the bottom of .scrutinizer.yml. - 2.7 - - 3.3 - 3.4 - 3.5 - 3.6 @@ -26,16 +25,12 @@ eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) nightly-x64"; pip install -q scrutinizer-ocular tox-travis; else - pip install -q flake8 flake8-import-order flake8-docstrings pep8-naming; + pip install -q tox; fi install: - pip install . script: - - if [ $CI_TARGET = tests ]; then - tox; - else - flake8 neovim; - fi + - tox after_script: - if [ $CI_TARGET = tests ]; then ocular; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/README.md new/python-client-0.2.4/README.md --- old/python-client-0.2.0/README.md 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/README.md 2018-03-06 17:22:22.000000000 +0100 @@ -9,7 +9,7 @@ #### Installation -Supports python 2.7, and 3.3 or later. +Supports python 2.7, and 3.4 or later. ```sh pip2 install neovim @@ -83,9 +83,11 @@ #### Remote (new-style) plugins -Neovim allows python plugins to be defined by placing python files or packages -in `rplugin/python3/` (in a runtimepath folder). These follow the structure of -this example: +Neovim allows python3 plugins to be defined by placing python files or packages +in `rplugin/python3/` (in a runtimepath folder). Python2 rplugins are also +supported and placed in `rplugin/python/`, but are considered deprecated. +Further added library features will only be available on python3. Rplugins follow +the structure of this example: ```python import neovim diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/Makefile new/python-client-0.2.4/docs/Makefile --- old/python-client-0.2.0/docs/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/Makefile 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = Neovim +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/api/buffer.rst new/python-client-0.2.4/docs/api/buffer.rst --- old/python-client-0.2.0/docs/api/buffer.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/api/buffer.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,5 @@ +Buffer Class +============ + +.. autoclass:: neovim.api.Buffer + :members: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/api/nvim.rst new/python-client-0.2.4/docs/api/nvim.rst --- old/python-client-0.2.0/docs/api/nvim.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/api/nvim.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,7 @@ +Nvim Class +========== + +An instance of this class is used by remote plugins. + +.. autoclass:: neovim.api.Nvim + :members: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/api/tabpage.rst new/python-client-0.2.4/docs/api/tabpage.rst --- old/python-client-0.2.0/docs/api/tabpage.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/api/tabpage.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,5 @@ +Tabpage Class +============= + +.. autoclass:: neovim.api.Tabpage + :members: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/api/window.rst new/python-client-0.2.4/docs/api/window.rst --- old/python-client-0.2.0/docs/api/window.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/api/window.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,5 @@ +Window Class +============ + +.. autoclass:: neovim.api.Window + :members: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/conf.py new/python-client-0.2.4/docs/conf.py --- old/python-client-0.2.0/docs/conf.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/conf.py 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Neovim documentation build configuration file, created by +# sphinx-quickstart on Sat Feb 3 12:15:22 2018. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('./')) +import datetime + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.autodoc', + 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Neovim Python Client' +copyright = '2014 - {year}, Neovim'.format( + year=datetime.datetime.now().year +) +author = 'Neovim' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '' +# The full version, including alpha/beta/rc tags. +release = '' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Neovimdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'Neovim.tex', 'Neovim Documentation', + 'Neovim', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'neovim', 'Neovim Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Neovim', 'Neovim Documentation', + author, 'Neovim', 'One line description of project.', + 'Miscellaneous'), +] + + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/development.rst new/python-client-0.2.4/docs/development.rst --- old/python-client-0.2.0/docs/development.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/development.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,89 @@ +Development +=========== + +If you change the code, you need to run:: + + pip2 install . + pip3 install . + +for the changes to have effect. +Alternatively you could execute Neovim with the ``$PYTHONPATH`` environment variable:: + + PYTHONPATH=/path/to/python-client nvim + +But note this is not completely reliable, +as installed packages can appear before ``$PYTHONPATH`` in the python search path. + +You need to rerun this command if you have changed the code, +in order for Neovim to use it for the plugin host. + +To run the tests execute:: + + nosetests + +This will run the tests in an embedded instance of Neovim. +If you want to test a different version than ``nvim`` in ``$PATH`` use:: + + NVIM_CHILD_ARGV='["/path/to/nvim", "-u", "NONE", "--embed"]' nosetests + +Alternatively, if you want to see the state of nvim, you could use:: + + export NVIM_LISTEN_ADDRESS=/tmp/nvimtest + xterm -e "nvim -u NONE"& + nosetests + +But note you need to restart Neovim every time you run the tests! +Substitute your favorite terminal emulator for ``xterm``. + +Troubleshooting +--------------- + +You can run the plugin host in Neovim with logging enabled to debug errors:: + + NVIM_PYTHON_LOG_FILE=logfile NVIM_PYTHON_LOG_LEVEL=DEBUG nvim + +As more than one Python host process might be started, +the log filenames take the pattern ``logfile_pyX_KIND`` +where ``X`` is the major python version (2 or 3) +and ``KIND`` is either "rplugin" or "script" (for the ``:python[3]`` script interface). + +If the host cannot start at all, +the error could be found in ``~/.nvimlog`` if ``nvim`` was compiled with logging. + +Usage through the Python REPL +----------------------------- + +A number of different transports are supported, +but the simplest way to get started is with the python REPL. +First, start Neovim with a known address (or use the ``$NVIM_LISTEN_ADDRESS`` of a running instance):: + + NVIM_LISTEN_ADDRESS=/tmp/nvim nvim + +In another terminal, +connect a python REPL to Neovim (note that the API is similar to the one exposed by the `python-vim bridge`_): + +.. code-block:: python + + >>> from neovim import attach + # Create a python API session attached to unix domain socket created above: + >>> nvim = attach('socket', path='/tmp/nvim') + # Now do some work. + >>> buffer = nvim.current.buffer # Get the current buffer + >>> buffer[0] = 'replace first line' + >>> buffer[:] = ['replace whole buffer'] + >>> nvim.command('vsplit') + >>> nvim.windows[1].width = 10 + >>> nvim.vars['global_var'] = [1, 2, 3] + >>> nvim.eval('g:global_var') + [1, 2, 3] + +.. _`python-vim bridge`: http://vimdoc.sourceforge.net/htmldoc/if_pyth.html#python-vim + +You can embed Neovim into your python application instead of binding to a running neovim instance: + +.. code-block:: python + + >>> from neovim import attach + >>> nvim = attach('child', argv=["/bin/env", "nvim", "--embed"]) + +The tests can be consulted for more examples. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/index.rst new/python-client-0.2.4/docs/index.rst --- old/python-client-0.2.0/docs/index.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/index.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,36 @@ +Neovim Python Client +==================== + +Implements support for Python plugins in `Neovim`_. +Also works as a library for connecting to and scripting Neovim processes through its msgpack-rpc API. + +.. _`Neovim`: http://neovim.io/ + +.. toctree:: + :caption: Getting started + :maxdepth: 2 + + installation + +.. toctree:: + :caption: Usage + :maxdepth: 2 + + usage/python-plugin-api + usage/remote-plugins + +.. toctree:: + :caption: API documentation + :maxdepth: 2 + + plugin-decorators + api/nvim + api/buffer + api/window + api/tabpage + +.. toctree:: + :caption: Development + :maxdepth: 2 + + development diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/installation.rst new/python-client-0.2.4/docs/installation.rst --- old/python-client-0.2.0/docs/installation.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/installation.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,36 @@ +Installation +============ + +The Neovim Python client supports Python 2.7, and 3.4 or later. + +Using pip +--------- + +You can install the package without being root by adding the ``--user`` flag:: + + pip2 install neovim + pip3 install neovim + +.. note:: + + If you only use one of python2 or python3, + it is enough to install that version. + +If you follow Neovim master, +make sure to upgrade the ``python-client`` when you upgrade Neovim:: + + pip2 install --upgrade neovim + pip3 install --upgrade neovim + +Install from source +------------------- + +Clone the repository somewhere on your disk and enter to the repository:: + + git clone https://github.com/neovim/python-client.git + cd python-client + +Now you can install it on your system:: + + pip2 install . + pip3 install . diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/make.bat new/python-client-0.2.4/docs/make.bat --- old/python-client-0.2.0/docs/make.bat 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/make.bat 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=Neovim + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/plugin-decorators.rst new/python-client-0.2.4/docs/plugin-decorators.rst --- old/python-client-0.2.0/docs/plugin-decorators.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/plugin-decorators.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,26 @@ +Plugin Decorators +================= + +.. module:: neovim.plugin + +Plugin decorators. + +Plugin +------ + +.. autofunction:: plugin + +Command +------- + +.. autofunction:: command + +Autocmd +------- + +.. autofunction:: autocmd + +Function +-------- + +.. autofunction:: function diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/usage/python-plugin-api.rst new/python-client-0.2.4/docs/usage/python-plugin-api.rst --- old/python-client-0.2.0/docs/usage/python-plugin-api.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/usage/python-plugin-api.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,64 @@ +Python Plugin API +================= + +Neovim has a new mechanism for defining plugins, +as well as a number of extensions to the python API. +The API extensions are accessible no matter if the traditional ``:python`` interface or the new mechanism is used, +as discussed on :doc:`remote-plugins`. + +``vim.funcs`` +------------- + +Exposes vimscript functions (both builtin and global user defined functions) as a python namespace. +For instance to set the value of a register: + +.. code-block:: python + + vim.funcs.setreg('0', ["some", "text"], 'l') + +``vim.api`` +----------- + +Exposes Neovim API methods. +For instance to call ``nvim_strwidth``: + +.. code-block:: python + + result = vim.api.strwidth("some text") + +Note the initial ``nvim_`` is not included. +Also, object methods can be called directly on their object: + +.. code-block:: python + + buf = vim.current.buffer + len = buf.api.line_count() + +calls ``nvim_buf_line_count``. +Alternatively msgpack requests can be invoked directly: + +.. code-block:: python + + result = vim.request("nvim_strwith", "some text") + len = vim.request("nvim_buf_line_count", buf) + +Async calls +----------- + +The API is not thread-safe in general. +However, ``vim.async_call`` allows a spawned thread to schedule code to be executed on the main thread. +This method could also be called from ``:python`` or a synchronous request handler, +to defer some execution that shouldn't block Neovim: + +.. code-block:: vim + + :python vim.async_call(myfunc, args...) + +Note that this code will still block the plugin host if it does long-running computations. +Intensive computations should be done in a separate thread (or process), +and ``vim.async_call`` can be used to send results back to Neovim. + +Some methods accept an ``async`` keyword argument: +``vim.eval``, ``vim.command``, ``vim.request`` as well as the ``vim.funcs`` and ``vim.api`` wrappers. +When ``async=True`` is passed the client will not wait for Neovim to complete the request +(which also means that the return value is unavailable). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/docs/usage/remote-plugins.rst new/python-client-0.2.4/docs/usage/remote-plugins.rst --- old/python-client-0.2.0/docs/usage/remote-plugins.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/docs/usage/remote-plugins.rst 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,47 @@ +.. _remote-plugins: +Remote (new-style) plugins +========================== + +Neovim allows Python 3 plugins to be defined by placing python files or packages in ``rplugin/python3/`` (in a ``runtimepath`` folder). +Python 2 rplugins are also supported and placed in ``rplugin/python/``, +but are considered deprecated. +Further added library features will only be available on Python 3. +Rplugins follow the structure of this example: + +.. code-block:: python + + import neovim + + @neovim.plugin + class TestPlugin(object): + + def __init__(self, nvim): + self.nvim = nvim + + @neovim.function('TestFunction', sync=True) + def testfunction(self, args): + return 3 + + @neovim.command('TestCommand', nargs='*', range='') + def testcommand(self, args, range): + self.nvim.current.line = ('Command with args: {}, range: {}' + .format(args, range)) + + @neovim.autocmd('BufEnter', pattern='*.py', eval='expand("<afile>")', sync=True) + def on_bufenter(self, filename): + self.nvim.out_write('testplugin is in ' + filename + '\n') + +If ``sync=True`` is supplied Neovim 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 Neovim 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 Neovim requests, +but it can make asynchronous requests, i.e. passing ``async=True``. + +You need to run ``:UpdateRemotePlugins`` in Neovim for changes in the specifications to have effect. +For details see ``:help remote-plugin`` in Neovim. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/__init__.py new/python-client-0.2.4/neovim/__init__.py --- old/python-client-0.2.0/neovim/__init__.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/__init__.py 2018-03-06 17:22:22.000000000 +0100 @@ -21,7 +21,7 @@ 'shutdown_hook', 'attach', 'setup_logging', 'ErrorResponse') -VERSION = Version(major=0, minor=2, patch=0, prerelease='') +VERSION = Version(major=0, minor=2, patch=4, prerelease='') def start_host(session=None): @@ -96,6 +96,18 @@ nvim = attach('socket', path=<path>) nvim = attach('child', argv=<argv>) nvim = attach('stdio') + + When the session is not needed anymore, it is recommended to explicitly + close it: + nvim.close() + It is also possible to use the session as a context mangager: + with attach('socket', path=thepath) as nvim: + print(nvim.funcs.getpid()) + print(nvim.current.line) + This will automatically close the session when you're done with it, or + when an error occured. + + """ session = (tcp_session(address, port) if session_type == 'tcp' else socket_session(path) if session_type == 'socket' else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/api/nvim.py new/python-client-0.2.4/neovim/api/nvim.py --- old/python-client-0.2.0/neovim/api/nvim.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/api/nvim.py 2018-03-06 17:22:22.000000000 +0100 @@ -1,7 +1,7 @@ """Main Nvim interface.""" -import functools import os import sys +from functools import partial from traceback import format_stack from msgpack import ExtType @@ -36,6 +36,12 @@ `SubClass.from_nvim(nvim)` where `SubClass` is a subclass of `Nvim`, which is useful for having multiple `Nvim` objects that behave differently without one affecting the other. + + When this library is used on python3.4+, asyncio event loop is guaranteed + to be used. It is available as the "loop" attribute of this class. Note + that asyncio callbacks cannot make blocking requests, which includes + accessing state-dependent attributes. They should instead schedule another + callback using nvim.async_call, which will not have this restriction. """ @classmethod @@ -90,6 +96,10 @@ self._decode = decode self._err_cb = err_cb + # only on python3.4+ we expose asyncio + if IS_PYTHON3 and os.name != 'nt': + self.loop = self._session.loop._loop + def _from_nvim(self, obj, decode=None): if decode is None: decode = self._decode @@ -180,6 +190,21 @@ """Stop the event loop being started with `run_loop`.""" self._session.stop() + def close(self): + """Close the nvim session and release its resources.""" + self._session.close() + + def __enter__(self): + """Enter nvim session as a context manager.""" + return self + + def __exit__(self, *exc_info): + """Exit nvim session as a context manager. + + Closes the event loop. + """ + self.close() + def with_decode(self, decode=True): """Initialize a new Nvim instance.""" return Nvim(self._session, self.channel_id, @@ -439,7 +464,7 @@ self._nvim = nvim def __getattr__(self, name): - return functools.partial(self._nvim.call, name) + return partial(self._nvim.call, name) class NvimError(Exception): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/async_session.py new/python-client-0.2.4/neovim/msgpack_rpc/async_session.py --- old/python-client-0.2.0/neovim/msgpack_rpc/async_session.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/async_session.py 2018-03-06 17:22:22.000000000 +0100 @@ -27,6 +27,7 @@ 1: self._on_response, 2: self._on_notification } + self.loop = msgpack_stream.loop def threadsafe_call(self, fn): """Wrapper around `MsgpackStream.threadsafe_call`.""" @@ -70,6 +71,10 @@ """Stop the event loop.""" self._msgpack_stream.stop() + def close(self): + """Close the event loop.""" + self._msgpack_stream.close() + def _on_message(self, msg): try: self._handlers.get(msg[0], self._on_invalid_message)(msg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/__init__.py new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/__init__.py --- old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/__init__.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/__init__.py 2018-03-06 17:22:22.000000000 +0100 @@ -2,15 +2,25 @@ Tries to use pyuv as a backend, falling back to the asyncio implementation. """ -try: - # libuv is fully implemented in C, use it when available - from .uv import UvEventLoop - EventLoop = UvEventLoop -except ImportError: - # asyncio(trollius on python 2) is pure python and should be more portable - # across python implementations + +import os + +from ...compat import IS_PYTHON3 + +# on python3 we only support asyncio, as we expose it to plugins +if IS_PYTHON3 and os.name != 'nt': from .asyncio import AsyncioEventLoop EventLoop = AsyncioEventLoop +else: + try: + # libuv is fully implemented in C, use it when available + from .uv import UvEventLoop + EventLoop = UvEventLoop + except ImportError: + # asyncio(trollius on python 2) is pure python and should be more + # portable across python implementations + from .asyncio import AsyncioEventLoop + EventLoop = AsyncioEventLoop __all__ = ('EventLoop') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/asyncio.py new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/asyncio.py --- old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/asyncio.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/asyncio.py 2018-03-06 17:22:22.000000000 +0100 @@ -39,6 +39,7 @@ def connection_made(self, transport): """Used to signal `asyncio.Protocol` of a successful connection.""" self._transport = transport + self._raw_transport = transport if isinstance(transport, asyncio.SubprocessTransport): self._transport = transport.get_pipe_transport(0) @@ -74,6 +75,7 @@ self._loop = loop_cls() self._queued_data = deque() self._fact = lambda: self + self._raw_transport = None def _connect_tcp(self, address, port): coroutine = self._loop.create_connection(self._fact, address, port) @@ -112,6 +114,11 @@ def _stop(self): self._loop.stop() + def _close(self): + if self._raw_transport is not None: + self._raw_transport.close() + self._loop.close() + def _threadsafe_call(self, fn): self._loop.call_soon_threadsafe(fn) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/base.py new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/base.py --- old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/base.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/base.py 2018-03-06 17:22:22.000000000 +0100 @@ -85,7 +85,11 @@ self._on_data = None self._error = None self._init() - getattr(self, '_connect_{}'.format(transport_type))(*args) + try: + getattr(self, '_connect_{}'.format(transport_type))(*args) + except Exception as e: + self.close() + raise e self._start_reading() def connect_tcp(self, address, port): @@ -148,6 +152,11 @@ self._stop() debug('Stopped event loop') + def close(self): + """Stop the event loop.""" + self._close() + debug('Closed event loop') + def _on_signal(self, signum): msg = 'Received {}'.format(self._signames[signum]) debug(msg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/uv.py new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/uv.py --- old/python-client-0.2.0/neovim/msgpack_rpc/event_loop/uv.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/event_loop/uv.py 2018-03-06 17:22:22.000000000 +0100 @@ -97,6 +97,9 @@ def _stop(self): self._loop.stop() + def _close(self): + pass + def _threadsafe_call(self, fn): self._callbacks.append(fn) self._async.send() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/msgpack_stream.py new/python-client-0.2.4/neovim/msgpack_rpc/msgpack_stream.py --- old/python-client-0.2.0/neovim/msgpack_rpc/msgpack_stream.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/msgpack_stream.py 2018-03-06 17:22:22.000000000 +0100 @@ -19,19 +19,20 @@ def __init__(self, event_loop): """Wrap `event_loop` on a msgpack-aware interface.""" - self._event_loop = event_loop - self._packer = Packer(unicode_errors=unicode_errors_default) + self.loop = event_loop + self._packer = Packer(encoding='utf-8', + unicode_errors=unicode_errors_default) self._unpacker = Unpacker() self._message_cb = None def threadsafe_call(self, fn): """Wrapper around `BaseEventLoop.threadsafe_call`.""" - self._event_loop.threadsafe_call(fn) + self.loop.threadsafe_call(fn) def send(self, msg): """Queue `msg` for sending to Nvim.""" debug('sent %s', msg) - self._event_loop.send(self._packer.pack(msg)) + self.loop.send(self._packer.pack(msg)) def run(self, message_cb): """Run the event loop to receive messages from Nvim. @@ -40,12 +41,16 @@ a message has been successfully parsed from the input stream. """ self._message_cb = message_cb - self._event_loop.run(self._on_data) + self.loop.run(self._on_data) self._message_cb = None def stop(self): """Stop the event loop.""" - self._event_loop.stop() + self.loop.stop() + + def close(self): + """Close the event loop.""" + self.loop.close() def _on_data(self, data): self._unpacker.feed(data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/msgpack_rpc/session.py new/python-client-0.2.4/neovim/msgpack_rpc/session.py --- old/python-client-0.2.0/neovim/msgpack_rpc/session.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/msgpack_rpc/session.py 2018-03-06 17:22:22.000000000 +0100 @@ -26,6 +26,7 @@ self._pending_messages = deque() self._is_running = False self._setup_exception = None + self.loop = async_session.loop def threadsafe_call(self, fn, *args, **kwargs): """Wrapper around `AsyncSession.threadsafe_call`.""" @@ -140,6 +141,10 @@ """Stop the event loop.""" self._async_session.stop() + def close(self): + """Close the event loop.""" + self._async_session.close() + def _yielding_request(self, method, args): gr = greenlet.getcurrent() parent = gr.parent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/plugin/decorators.py new/python-client-0.2.4/neovim/plugin/decorators.py --- old/python-client-0.2.0/neovim/plugin/decorators.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/plugin/decorators.py 2018-03-06 17:22:22.000000000 +0100 @@ -55,7 +55,7 @@ if range is not None: opts['range'] = '' if range is True else str(range) - elif count: + elif count is not None: opts['count'] = count if bang: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/neovim/plugin/script_host.py new/python-client-0.2.4/neovim/plugin/script_host.py --- old/python-client-0.2.0/neovim/plugin/script_host.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/neovim/plugin/script_host.py 2018-03-06 17:22:22.000000000 +0100 @@ -24,6 +24,10 @@ if sys.version_info >= (3, 4): from importlib.machinery import PathFinder + PYTHON_SUBDIR = 'python3' +else: + PYTHON_SUBDIR = 'python2' + @plugin class ScriptHost(object): @@ -236,16 +240,11 @@ def discover_runtime_directories(nvim): rv = [] - for path in nvim.list_runtime_paths(): - if not os.path.exists(path): + for rtp in nvim.list_runtime_paths(): + if not os.path.exists(rtp): continue - path1 = os.path.join(path, 'pythonx') - if IS_PYTHON3: - path2 = os.path.join(path, 'python3') - else: - path2 = os.path.join(path, 'python2') - if os.path.exists(path1): - rv.append(path1) - if os.path.exists(path2): - rv.append(path2) + for subdir in ['pythonx', PYTHON_SUBDIR]: + path = os.path.join(rtp, subdir) + if os.path.exists(path): + rv.append(path) return rv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/setup.py new/python-client-0.2.4/setup.py --- old/python-client-0.2.0/setup.py 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/setup.py 2018-03-06 17:22:22.000000000 +0100 @@ -5,11 +5,8 @@ from setuptools import setup install_requires = [ - 'msgpack-python>=0.4.0', + 'msgpack>=0.5.0', ] -extras_require = { - 'pyuv': ['pyuv>=1.0.0'], -} if os.name == 'nt': install_requires.append('pyuv>=1.0.0') @@ -22,15 +19,14 @@ install_requires.append('greenlet') setup(name='neovim', - version='0.2.0', + version='0.2.4', description='Python client to neovim', url='http://github.com/neovim/python-client', - download_url='https://github.com/neovim/python-client/archive/0.2.0.tar.gz', + download_url='https://github.com/neovim/python-client/archive/0.2.4.tar.gz', author='Thiago de Arruda', author_email='tpadilh...@gmail.com', license='Apache', packages=['neovim', 'neovim.api', 'neovim.msgpack_rpc', 'neovim.msgpack_rpc.event_loop', 'neovim.plugin'], install_requires=install_requires, - extras_require=extras_require, zip_safe=False) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/test/test_decorators.py new/python-client-0.2.4/test/test_decorators.py --- old/python-client-0.2.0/test/test_decorators.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-client-0.2.4/test/test_decorators.py 2018-03-06 17:22:22.000000000 +0100 @@ -0,0 +1,30 @@ +from nose.tools import with_setup, eq_ as eq, ok_ as ok + +from neovim.plugin.decorators import command + + +def test_command_count(): + def function(): + "A dummy function to decorate." + return + + # ensure absence with default value of None + decorated = command('test')(function) + ok('count' not in decorated._nvim_rpc_spec['opts']) + + # ensure absence with explicit value of None + count_value = None + decorated = command('test', count=count_value)(function) + ok('count' not in decorated._nvim_rpc_spec['opts']) + + # Test presesence with value of 0 + count_value = 0 + decorated = command('test', count=count_value)(function) + ok('count' in decorated._nvim_rpc_spec['opts']) + eq(decorated._nvim_rpc_spec['opts']['count'], count_value) + + # Test presence with value of 1 + count_value = 1 + decorated = command('test', count=count_value)(function) + ok('count' in decorated._nvim_rpc_spec['opts']) + eq(decorated._nvim_rpc_spec['opts']['count'], count_value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-client-0.2.0/tox.ini new/python-client-0.2.4/tox.ini --- old/python-client-0.2.0/tox.ini 2017-11-08 19:29:13.000000000 +0100 +++ new/python-client-0.2.4/tox.ini 2018-03-06 17:22:22.000000000 +0100 @@ -1,7 +1,26 @@ [tox] -envlist = py{27,33,34,35,36}-{asyncio,pyuv},pypy +envlist = + py{27,34,35,36}-{asyncio,pyuv},pypy + py36-docs + [testenv] deps= nose pyuv: pyuv commands=nosetests + +[testenv:checkqa] +deps = + flake8 + flake8-import-order + flake8-docstrings + pep8-naming +commands = flake8 {posargs:neovim} + +[testenv:docs] +deps = + Sphinx + sphinx_rtd_theme +changedir = {toxinidir}/docs +commands = + sphinx-build -b html -d {envtmpdir}/doctrees . {envtmpdir}/html