forked from pythonic-emacs/anaconda-mode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanaconda_mode.py
160 lines (117 loc) · 4.13 KB
/
anaconda_mode.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
anaconda_mode
~~~~~~~~~~~~~
This is anaconda_mode autocompletion server.
:copyright: (c) 2013-2015 by Artem Malyshev.
:license: GPL3, see LICENSE for more details.
"""
from __future__ import (
absolute_import, unicode_literals, division, print_function)
import sys
from functools import wraps
from os.path import abspath, dirname
from pkg_resources import get_distribution, DistributionNotFound
from subprocess import Popen
project_path = dirname(abspath(__file__))
sys.path.insert(0, project_path)
missing_dependencies = []
try:
from jedi import Script, NotFoundError
except ImportError:
missing_dependencies.append('jedi')
try:
from service_factory import service_factory
except ImportError:
missing_dependencies.append('service_factory')
if missing_dependencies:
command = ['pip', 'install', '-t', project_path] + missing_dependencies
pip = Popen(command)
pip.communicate()
assert pip.returncode is 0, 'PyPi installation fails.'
from jedi import Script, NotFoundError
from service_factory import service_factory
print('Python executable:', sys.executable)
for package in ['jedi', 'service_factory']:
try:
version = get_distribution(package).version
except DistributionNotFound:
print('Unable to find {package} version'.format(package=package))
else:
print('{package} version: {version}'.format(
package=package, version=version))
def script_method(f):
"""Create jedi.Script instance and apply f to it."""
@wraps(f)
def wrapper(source, line, column, path):
try:
return f(Script(source, line, column, path))
except NotFoundError:
return []
return wrapper
@script_method
def complete(script):
"""Select auto-complete candidates for source position."""
def first_line(text):
"""Return text first line."""
return text.strip().split('\n', 1)[0]
return [{'name': comp.name,
'doc': comp.docstring() or None,
'info': first_line(comp.docstring(raw=True)) or None,
'type': comp.type,
'path': comp.module_path or None,
'line': comp.line}
for comp in script.completions()]
@script_method
def doc(script):
"""Documentation for all definitions at point."""
docs = ['\n'.join([d.module_name + ' - ' + d.description,
'=' * 40,
d.docstring() or "- No docstring -"]).strip()
for d in script.goto_definitions()]
return ('\n' + '-' * 40 + '\n').join(docs)
def process_definitions(f):
@wraps(f)
def wrapper(script):
cache = {script.path: script.source.splitlines()}
def get_description(d):
if d.module_path not in cache:
with open(d.module_path, 'r') as file:
cache[d.module_path] = file.read().splitlines()
return cache[d.module_path][d.line - 1]
return [{'line': d.line,
'column': d.column,
'name': d.name,
'description': get_description(d),
'module': d.module_name,
'type': d.type,
'path': d.module_path}
for d in f(script) if not d.in_builtin_module()]
return wrapper
@script_method
@process_definitions
def goto_definitions(script):
return script.goto_definitions()
@script_method
@process_definitions
def goto_assignments(script):
return script.goto_assignments()
@script_method
@process_definitions
def usages(script):
return script.usages()
@script_method
def eldoc(script):
"""Return eldoc format documentation string or ''."""
signatures = script.call_signatures()
if len(signatures) == 1:
sgn = signatures[0]
return {
'name': sgn.name,
'index': sgn.index,
'params': [p.description for p in sgn.params]
}
return {}
app = [complete, doc, goto_definitions, goto_assignments, usages, eldoc]
if __name__ == '__main__':
host = sys.argv[1] if len(sys.argv) == 2 else '127.0.0.1'
service_factory(app, host, 'auto', 'anaconda_mode port {port}')