|
1 | 1 | """Python client for Nvim. |
2 | 2 |
|
3 | | -Client library for talking with Nvim processes via it's msgpack-rpc API. |
| 3 | +This is a transition package. New projects should instead import pynvim package. |
4 | 4 | """ |
5 | | -import logging |
6 | | -import os |
7 | | -import sys |
| 5 | +import pynvim |
| 6 | +from pynvim import * |
8 | 7 |
|
9 | | -from .api import Nvim |
10 | | -from .compat import IS_PYTHON3 |
11 | | -from .msgpack_rpc import (ErrorResponse, child_session, socket_session, |
12 | | - stdio_session, tcp_session) |
13 | | -from .plugin import (Host, autocmd, command, decode, encoding, function, |
14 | | - plugin, rpc_export, shutdown_hook) |
15 | | -from .util import VERSION, Version |
16 | | - |
17 | | - |
18 | | -__all__ = ('tcp_session', 'socket_session', 'stdio_session', 'child_session', |
19 | | - 'start_host', 'autocmd', 'command', 'encoding', 'decode', |
20 | | - 'function', 'plugin', 'rpc_export', 'Host', 'Nvim', 'Version', |
21 | | - 'VERSION', 'shutdown_hook', 'attach', 'setup_logging', |
22 | | - 'ErrorResponse') |
23 | | - |
24 | | - |
25 | | -def start_host(session=None): |
26 | | - """Promote the current process into python plugin host for Nvim. |
27 | | -
|
28 | | - Start msgpack-rpc event loop for `session`, listening for Nvim requests |
29 | | - and notifications. It registers Nvim commands for loading/unloading |
30 | | - python plugins. |
31 | | -
|
32 | | - The sys.stdout and sys.stderr streams are redirected to Nvim through |
33 | | - `session`. That means print statements probably won't work as expected |
34 | | - while this function doesn't return. |
35 | | -
|
36 | | - This function is normally called at program startup and could have been |
37 | | - defined as a separate executable. It is exposed as a library function for |
38 | | - testing purposes only. |
39 | | - """ |
40 | | - plugins = [] |
41 | | - for arg in sys.argv: |
42 | | - _, ext = os.path.splitext(arg) |
43 | | - if ext == '.py': |
44 | | - plugins.append(arg) |
45 | | - elif os.path.isdir(arg): |
46 | | - init = os.path.join(arg, '__init__.py') |
47 | | - if os.path.isfile(init): |
48 | | - plugins.append(arg) |
49 | | - |
50 | | - # This is a special case to support the old workaround of |
51 | | - # adding an empty .py file to make a package directory |
52 | | - # visible, and it should be removed soon. |
53 | | - for path in list(plugins): |
54 | | - dup = path + ".py" |
55 | | - if os.path.isdir(path) and dup in plugins: |
56 | | - plugins.remove(dup) |
57 | | - |
58 | | - # Special case: the legacy scripthost receives a single relative filename |
59 | | - # while the rplugin host will receive absolute paths. |
60 | | - if plugins == ["script_host.py"]: |
61 | | - name = "script" |
62 | | - else: |
63 | | - name = "rplugin" |
64 | | - |
65 | | - setup_logging(name) |
66 | | - |
67 | | - if not session: |
68 | | - session = stdio_session() |
69 | | - nvim = Nvim.from_session(session) |
70 | | - |
71 | | - if nvim.version.api_level < 1: |
72 | | - sys.stderr.write("This version of the neovim python package " |
73 | | - "requires nvim 0.1.6 or later") |
74 | | - sys.exit(1) |
75 | | - |
76 | | - host = Host(nvim) |
77 | | - host.start(plugins) |
78 | | - |
79 | | - |
80 | | -def attach(session_type, address=None, port=None, |
81 | | - path=None, argv=None, decode=None): |
82 | | - """Provide a nicer interface to create python api sessions. |
83 | | -
|
84 | | - Previous machinery to create python api sessions is still there. This only |
85 | | - creates a facade function to make things easier for the most usual cases. |
86 | | - Thus, instead of: |
87 | | - from neovim import socket_session, Nvim |
88 | | - session = tcp_session(address=<address>, port=<port>) |
89 | | - nvim = Nvim.from_session(session) |
90 | | - You can now do: |
91 | | - from neovim import attach |
92 | | - nvim = attach('tcp', address=<address>, port=<port>) |
93 | | - And also: |
94 | | - nvim = attach('socket', path=<path>) |
95 | | - nvim = attach('child', argv=<argv>) |
96 | | - nvim = attach('stdio') |
97 | | -
|
98 | | - When the session is not needed anymore, it is recommended to explicitly |
99 | | - close it: |
100 | | - nvim.close() |
101 | | - It is also possible to use the session as a context mangager: |
102 | | - with attach('socket', path=thepath) as nvim: |
103 | | - print(nvim.funcs.getpid()) |
104 | | - print(nvim.current.line) |
105 | | - This will automatically close the session when you're done with it, or |
106 | | - when an error occured. |
107 | | -
|
108 | | -
|
109 | | - """ |
110 | | - session = (tcp_session(address, port) if session_type == 'tcp' else |
111 | | - socket_session(path) if session_type == 'socket' else |
112 | | - stdio_session() if session_type == 'stdio' else |
113 | | - child_session(argv) if session_type == 'child' else |
114 | | - None) |
115 | | - |
116 | | - if not session: |
117 | | - raise Exception('Unknown session type "%s"' % session_type) |
118 | | - |
119 | | - if decode is None: |
120 | | - decode = IS_PYTHON3 |
121 | | - |
122 | | - return Nvim.from_session(session).with_decode(decode) |
123 | | - |
124 | | - |
125 | | -def setup_logging(name): |
126 | | - """Setup logging according to environment variables.""" |
127 | | - logger = logging.getLogger(__name__) |
128 | | - if 'NVIM_PYTHON_LOG_FILE' in os.environ: |
129 | | - prefix = os.environ['NVIM_PYTHON_LOG_FILE'].strip() |
130 | | - major_version = sys.version_info[0] |
131 | | - logfile = '{}_py{}_{}'.format(prefix, major_version, name) |
132 | | - handler = logging.FileHandler(logfile, 'w', 'utf-8') |
133 | | - handler.formatter = logging.Formatter( |
134 | | - '%(asctime)s [%(levelname)s @ ' |
135 | | - '%(filename)s:%(funcName)s:%(lineno)s] %(process)s - %(message)s') |
136 | | - logging.root.addHandler(handler) |
137 | | - level = logging.INFO |
138 | | - if 'NVIM_PYTHON_LOG_LEVEL' in os.environ: |
139 | | - lvl = getattr(logging, |
140 | | - os.environ['NVIM_PYTHON_LOG_LEVEL'].strip(), |
141 | | - level) |
142 | | - if isinstance(lvl, int): |
143 | | - level = lvl |
144 | | - logger.setLevel(level) |
145 | | - |
146 | | - |
147 | | -# Required for python 2.6 |
148 | | -class NullHandler(logging.Handler): |
149 | | - def emit(self, record): |
150 | | - pass |
151 | | - |
152 | | - |
153 | | -if not logging.root.handlers: |
154 | | - logging.root.addHandler(NullHandler()) |
| 8 | +__all__ = pynvim.__all__ |
0 commit comments