forked from python-mode/python-mode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvironment.py
More file actions
249 lines (188 loc) · 6.16 KB
/
environment.py
File metadata and controls
249 lines (188 loc) · 6.16 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
"""Define interfaces."""
import json
import os.path
import time
import vim # noqa
class VimPymodeEnviroment(object):
"""Vim User interface."""
prefix = '[Pymode]'
def __init__(self):
"""Init VIM environment."""
self.current = vim.current
self.options = dict(encoding=vim.eval('&enc'))
self.options['debug'] = self.var('g:pymode_debug', True)
@property
def curdir(self):
"""Return current working directory."""
return self.var('getcwd()')
@property
def curbuf(self):
"""Return current buffer."""
return self.current.buffer
@property
def cursor(self):
"""Return current window position.
:return tuple: (row, col)
"""
return self.current.window.cursor
@property
def source(self):
"""Return source of current buffer."""
return "\n".join(self.lines)
@property
def lines(self):
"""Iterate by lines in current file.
:return list:
"""
return self.curbuf
@staticmethod
def var(name, to_bool=False, silence=False, default=None):
"""Get vim variable.
:return vimobj:
"""
try:
value = vim.eval(name)
except vim.error:
if silence:
return default
raise
if to_bool:
try:
value = bool(int(value))
except ValueError:
value = value
return value
@staticmethod
def message(msg, history=False):
"""Show message to user.
:return: :None
"""
if history:
return vim.command('echom "%s"' % str(msg))
return vim.command('call pymode#wide_message("%s")' % str(msg))
def user_input(self, msg='', default=''):
"""Return user input or default.
:return str:
"""
prompt = []
prompt.append(str(self.prefix.strip()))
prompt.append(str(msg).strip())
if default != '':
prompt.append('[%s]' % default)
prompt.append('> ')
prompt = ' '.join([s for s in prompt if s])
vim.command('echohl Debug')
try:
input_str = vim.eval('input(%r)' % (prompt,))
except KeyboardInterrupt:
input_str = ''
vim.command('echohl none')
return input_str or default
def user_confirm(self, msg, yes=False):
"""Get user confirmation.
:return bool:
"""
default = 'yes' if yes else 'no'
action = self.user_input(msg, default)
return action and 'yes'.startswith(action)
def user_input_choices(self, msg, *options):
"""Get one of many options.
:return str: A choosen option
"""
choices = ['%s %s' % (self.prefix, msg)]
choices += [
"%s. %s" % (num, opt) for num, opt in enumerate(options, 1)]
try:
input_str = int(
vim.eval('inputlist(%s)' % self.prepare_value(choices)))
except (KeyboardInterrupt, ValueError):
input_str = 0
if not input_str:
self.message('Cancelled!')
return False
try:
return options[input_str - 1]
except (IndexError, ValueError):
self.error('Invalid option: %s' % input_str)
return self.user_input_choices(msg, *options)
@staticmethod
def error(msg):
"""Show error to user."""
vim.command('call pymode#error("%s")' % str(msg))
def debug(self, msg, *args):
"""Print debug information."""
if self.options.get('debug'):
print("%s %s [%s]" % (
int(time.time()), msg, ', '.join([str(a) for a in args])))
def stop(self, value=None):
"""Break Vim function."""
cmd = 'return'
if value is not None:
cmd += ' ' + self.prepare_value(value)
vim.command(cmd)
def catch_exceptions(self, func):
"""Decorator. Make execution more silence.
:return func:
"""
def _wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except (Exception, vim.error) as e: # noqa
if self.options.get('debug'):
raise
self.error(e)
return None
return _wrapper
def run(self, name, *args):
"""Run vim function."""
vim.command('call %s(%s)' % (name, ", ".join([
self.prepare_value(a) for a in args
])))
def let(self, name, value):
"""Set variable."""
cmd = 'let %s = %s' % (name, self.prepare_value(value))
self.debug(cmd)
vim.command(cmd)
def prepare_value(self, value, dumps=True):
"""Decode bstr to vim encoding.
:return unicode string:
"""
if dumps:
value = json.dumps(value)
return value
def get_offset_params(self, cursor=None, base=""):
"""Calculate current offset.
:return tuple: (source, offset)
"""
row, col = cursor or env.cursor
source = ""
offset = 0
for i, line in enumerate(self.lines, 1):
if i == row:
source += line[:col] + base
offset = len(source)
source += line[col:]
else:
source += line
source += '\n'
env.debug('Get offset', base or None, row, col, offset)
return source, offset
@staticmethod
def goto_line(line):
"""Go to line."""
vim.command('normal %sggzz' % line)
def goto_file(self, path, cmd='e', force=False):
"""Open file by path."""
if force or os.path.abspath(path) != self.curbuf.name:
self.debug('read', path)
if ' ' in path and os.name == 'posix':
path = path.replace(' ', '\\ ')
vim.command("%s %s" % (cmd, path))
@staticmethod
def goto_buffer(bufnr):
"""Open buffer."""
if str(bufnr) != '-1':
vim.command('buffer %s' % bufnr)
def select_line(self, start, end):
vim.command('normal %sggV%sgg' % (start, end))
env = VimPymodeEnviroment()