80 lines
2 KiB
Python
80 lines
2 KiB
Python
""" Code runnning support. """
|
|
import sys
|
|
from re import compile as re
|
|
|
|
from ._compat import StringIO
|
|
from .environment import env
|
|
|
|
|
|
encoding = re(r'#.*coding[:=]\s*([-\w.]+)')
|
|
|
|
|
|
def run_code():
|
|
""" Run python code in current buffer.
|
|
|
|
:returns: None
|
|
|
|
"""
|
|
errors, err = [], ''
|
|
line1, line2 = env.var('a:line1'), env.var('a:line2')
|
|
lines = __prepare_lines(line1, line2)
|
|
if encoding.match(lines[0]):
|
|
lines.pop(0)
|
|
if encoding.match(lines[0]):
|
|
lines.pop(0)
|
|
elif encoding.match(lines[1]):
|
|
lines.pop(1)
|
|
|
|
context = dict(
|
|
__name__='__main__',
|
|
__file__=env.var('expand("%:p")'),
|
|
input=env.user_input,
|
|
raw_input=env.user_input)
|
|
|
|
sys.stdout, stdout_ = StringIO(), sys.stdout
|
|
sys.stderr, stderr_ = StringIO(), sys.stderr
|
|
|
|
try:
|
|
code = compile('\n'.join(lines) + '\n', env.curbuf.name, 'exec')
|
|
sys.path.insert(0, env.curdir)
|
|
exec(code, context) # noqa
|
|
sys.path.pop(0)
|
|
|
|
except SystemExit as e:
|
|
if e.code:
|
|
# A non-false code indicates abnormal termination.
|
|
# A false code will be treated as a
|
|
# successful run, and the error will be hidden from Vim
|
|
env.error("Script exited with code %s" % e.code)
|
|
return env.stop()
|
|
|
|
except Exception:
|
|
import traceback
|
|
err = traceback.format_exc()
|
|
|
|
else:
|
|
err = sys.stderr.getvalue()
|
|
|
|
output = sys.stdout.getvalue()
|
|
output = env.prepare_value(output, dumps=False)
|
|
sys.stdout, sys.stderr = stdout_, stderr_
|
|
|
|
errors += [er for er in err.splitlines() if er and "<string>" not in er]
|
|
|
|
env.let('l:traceback', errors[2:])
|
|
env.let('l:output', [s for s in output.splitlines()])
|
|
|
|
|
|
def __prepare_lines(line1, line2):
|
|
|
|
lines = [l.rstrip() for l in env.lines[int(line1) - 1:int(line2)]]
|
|
|
|
indent = 0
|
|
for line in lines:
|
|
if line:
|
|
indent = len(line) - len(line.lstrip())
|
|
break
|
|
|
|
if len(lines) == 1:
|
|
lines.append('')
|
|
return [l[indent:] for l in lines]
|