Skip to content

Commit

Permalink
rename package to pynvim, add transition package
Browse files Browse the repository at this point in the history
  • Loading branch information
bfredl committed Nov 17, 2018
1 parent 1288426 commit f237238
Show file tree
Hide file tree
Showing 35 changed files with 210 additions and 181 deletions.
2 changes: 1 addition & 1 deletion docs/api/buffer.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Buffer Class
============

.. autoclass:: neovim.api.Buffer
.. autoclass:: pynvim.api.Buffer
:members:
2 changes: 1 addition & 1 deletion docs/api/nvim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ Nvim Class

An instance of this class is used by remote plugins.

.. autoclass:: neovim.api.Nvim
.. autoclass:: pynvim.api.Nvim
:members:
2 changes: 1 addition & 1 deletion docs/api/tabpage.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Tabpage Class
=============

.. autoclass:: neovim.api.Tabpage
.. autoclass:: pynvim.api.Tabpage
:members:
2 changes: 1 addition & 1 deletion docs/api/window.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Window Class
============

.. autoclass:: neovim.api.Window
.. autoclass:: pynvim.api.Window
:members:
8 changes: 4 additions & 4 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Using pip

You can install the package without being root by adding the ``--user`` flag::

pip2 install --user neovim
pip3 install --user neovim
pip2 install --user pynvim
pip3 install --user pynvim

.. note::

Expand All @@ -19,8 +19,8 @@ You can install the package without being root by adding the ``--user`` flag::
If you follow Neovim HEAD,
make sure to upgrade the ``python-client`` when you upgrade Neovim::

pip2 install --upgrade neovim
pip3 install --upgrade neovim
pip2 install --upgrade pynvim
pip3 install --upgrade pynvim

Install from source
-------------------
Expand Down
12 changes: 12 additions & 0 deletions dummy/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from setuptools import setup

setup(name='neovim',
version='0.3.1dev',
description='Transition packgage for pynvim',
url='http://github.com/neovim/python-client',
author='Thiago de Arruda',
author_email='tpadilha84@gmail.com',
license='Apache',
packages=[],
install_requires=['pynvim>=0.3.1dev'],
zip_safe=False)
154 changes: 4 additions & 150 deletions neovim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,154 +1,8 @@
"""Python client for Nvim.
Client library for talking with Nvim processes via it's msgpack-rpc API.
This is a transition package. New projects should instead import pynvim package.
"""
import logging
import os
import sys
import pynvim
from pynvim import *

from .api import Nvim
from .compat import IS_PYTHON3
from .msgpack_rpc import (ErrorResponse, child_session, socket_session,
stdio_session, tcp_session)
from .plugin import (Host, autocmd, command, decode, encoding, function,
plugin, rpc_export, shutdown_hook)
from .util import VERSION, Version


__all__ = ('tcp_session', 'socket_session', 'stdio_session', 'child_session',
'start_host', 'autocmd', 'command', 'encoding', 'decode',
'function', 'plugin', 'rpc_export', 'Host', 'Nvim', 'Version',
'VERSION', 'shutdown_hook', 'attach', 'setup_logging',
'ErrorResponse')


def start_host(session=None):
"""Promote the current process into python plugin host for Nvim.
Start msgpack-rpc event loop for `session`, listening for Nvim requests
and notifications. It registers Nvim commands for loading/unloading
python plugins.
The sys.stdout and sys.stderr streams are redirected to Nvim through
`session`. That means print statements probably won't work as expected
while this function doesn't return.
This function is normally called at program startup and could have been
defined as a separate executable. It is exposed as a library function for
testing purposes only.
"""
plugins = []
for arg in sys.argv:
_, ext = os.path.splitext(arg)
if ext == '.py':
plugins.append(arg)
elif os.path.isdir(arg):
init = os.path.join(arg, '__init__.py')
if os.path.isfile(init):
plugins.append(arg)

# This is a special case to support the old workaround of
# adding an empty .py file to make a package directory
# visible, and it should be removed soon.
for path in list(plugins):
dup = path + ".py"
if os.path.isdir(path) and dup in plugins:
plugins.remove(dup)

# Special case: the legacy scripthost receives a single relative filename
# while the rplugin host will receive absolute paths.
if plugins == ["script_host.py"]:
name = "script"
else:
name = "rplugin"

setup_logging(name)

if not session:
session = stdio_session()
nvim = Nvim.from_session(session)

if nvim.version.api_level < 1:
sys.stderr.write("This version of the neovim python package "
"requires nvim 0.1.6 or later")
sys.exit(1)

host = Host(nvim)
host.start(plugins)


def attach(session_type, address=None, port=None,
path=None, argv=None, decode=None):
"""Provide a nicer interface to create python api sessions.
Previous machinery to create python api sessions is still there. This only
creates a facade function to make things easier for the most usual cases.
Thus, instead of:
from neovim import socket_session, Nvim
session = tcp_session(address=<address>, port=<port>)
nvim = Nvim.from_session(session)
You can now do:
from neovim import attach
nvim = attach('tcp', address=<address>, port=<port>)
And also:
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
stdio_session() if session_type == 'stdio' else
child_session(argv) if session_type == 'child' else
None)

if not session:
raise Exception('Unknown session type "%s"' % session_type)

if decode is None:
decode = IS_PYTHON3

return Nvim.from_session(session).with_decode(decode)


def setup_logging(name):
"""Setup logging according to environment variables."""
logger = logging.getLogger(__name__)
if 'NVIM_PYTHON_LOG_FILE' in os.environ:
prefix = os.environ['NVIM_PYTHON_LOG_FILE'].strip()
major_version = sys.version_info[0]
logfile = '{}_py{}_{}'.format(prefix, major_version, name)
handler = logging.FileHandler(logfile, 'w', 'utf-8')
handler.formatter = logging.Formatter(
'%(asctime)s [%(levelname)s @ '
'%(filename)s:%(funcName)s:%(lineno)s] %(process)s - %(message)s')
logging.root.addHandler(handler)
level = logging.INFO
if 'NVIM_PYTHON_LOG_LEVEL' in os.environ:
lvl = getattr(logging,
os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(),
level)
if isinstance(lvl, int):
level = lvl
logger.setLevel(level)


# Required for python 2.6
class NullHandler(logging.Handler):
def emit(self, record):
pass


if not logging.root.handlers:
logging.root.addHandler(NullHandler())
__all__ = pynvim.__all__
15 changes: 4 additions & 11 deletions neovim/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
"""Nvim API subpackage.
This package implements a higher-level API that wraps msgpack-rpc `Session`
instances.
This is a transition package. New projects should instead import pynvim.api.
"""
from pynvim import api
from pynvim.api import *

from .buffer import Buffer
from .common import decode_if_bytes, walk
from .nvim import Nvim, NvimError
from .tabpage import Tabpage
from .window import Window


__all__ = ('Nvim', 'Buffer', 'Window', 'Tabpage', 'NvimError',
'decode_if_bytes', 'walk')
__all__ = api.__all__
154 changes: 154 additions & 0 deletions pynvim/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""Python client for Nvim.
Client library for talking with Nvim processes via its msgpack-rpc API.
"""
import logging
import os
import sys

from .api import Nvim, NvimError
from .compat import IS_PYTHON3
from .msgpack_rpc import (ErrorResponse, child_session, socket_session,
stdio_session, tcp_session)
from .plugin import (Host, autocmd, command, decode, encoding, function,
plugin, rpc_export, shutdown_hook)
from .util import VERSION, Version


__all__ = ('tcp_session', 'socket_session', 'stdio_session', 'child_session',
'start_host', 'autocmd', 'command', 'encoding', 'decode',
'function', 'plugin', 'rpc_export', 'Host', 'Nvim', 'NvimError',
'Version', 'VERSION', 'shutdown_hook', 'attach', 'setup_logging',
'ErrorResponse')


def start_host(session=None):
"""Promote the current process into python plugin host for Nvim.
Start msgpack-rpc event loop for `session`, listening for Nvim requests
and notifications. It registers Nvim commands for loading/unloading
python plugins.
The sys.stdout and sys.stderr streams are redirected to Nvim through
`session`. That means print statements probably won't work as expected
while this function doesn't return.
This function is normally called at program startup and could have been
defined as a separate executable. It is exposed as a library function for
testing purposes only.
"""
plugins = []
for arg in sys.argv:
_, ext = os.path.splitext(arg)
if ext == '.py':
plugins.append(arg)
elif os.path.isdir(arg):
init = os.path.join(arg, '__init__.py')
if os.path.isfile(init):
plugins.append(arg)

# This is a special case to support the old workaround of
# adding an empty .py file to make a package directory
# visible, and it should be removed soon.
for path in list(plugins):
dup = path + ".py"
if os.path.isdir(path) and dup in plugins:
plugins.remove(dup)

# Special case: the legacy scripthost receives a single relative filename
# while the rplugin host will receive absolute paths.
if plugins == ["script_host.py"]:
name = "script"
else:
name = "rplugin"

setup_logging(name)

if not session:
session = stdio_session()
nvim = Nvim.from_session(session)

if nvim.version.api_level < 1:
sys.stderr.write("This version of pynvim "
"requires nvim 0.1.6 or later")
sys.exit(1)

host = Host(nvim)
host.start(plugins)


def attach(session_type, address=None, port=None,
path=None, argv=None, decode=None):
"""Provide a nicer interface to create python api sessions.
Previous machinery to create python api sessions is still there. This only
creates a facade function to make things easier for the most usual cases.
Thus, instead of:
from pynvim import socket_session, Nvim
session = tcp_session(address=<address>, port=<port>)
nvim = Nvim.from_session(session)
You can now do:
from pynvim import attach
nvim = attach('tcp', address=<address>, port=<port>)
And also:
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
stdio_session() if session_type == 'stdio' else
child_session(argv) if session_type == 'child' else
None)

if not session:
raise Exception('Unknown session type "%s"' % session_type)

if decode is None:
decode = IS_PYTHON3

return Nvim.from_session(session).with_decode(decode)


def setup_logging(name):
"""Setup logging according to environment variables."""
logger = logging.getLogger(__name__)
if 'NVIM_PYTHON_LOG_FILE' in os.environ:
prefix = os.environ['NVIM_PYTHON_LOG_FILE'].strip()
major_version = sys.version_info[0]
logfile = '{}_py{}_{}'.format(prefix, major_version, name)
handler = logging.FileHandler(logfile, 'w', 'utf-8')
handler.formatter = logging.Formatter(
'%(asctime)s [%(levelname)s @ '
'%(filename)s:%(funcName)s:%(lineno)s] %(process)s - %(message)s')
logging.root.addHandler(handler)
level = logging.INFO
if 'NVIM_PYTHON_LOG_LEVEL' in os.environ:
lvl = getattr(logging,
os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(),
level)
if isinstance(lvl, int):
level = lvl
logger.setLevel(level)


# Required for python 2.6
class NullHandler(logging.Handler):
def emit(self, record):
pass


if not logging.root.handlers:
logging.root.addHandler(NullHandler())
Loading

0 comments on commit f237238

Please sign in to comment.