def eval_text(c, txt): if not txt: return vsc = get_vs(c) cvs = vsc.d txt = textwrap.dedent(txt) blocks = re.split('\n(?=[^\\s])', txt) leo_globals = {'c': c, 'p': c.p, 'g': g} ans = None dbg = False redirects = c.config.getBool('valuespace_vs_eval_redirect') if redirects: old_stderr = g.stdErrIsRedirected() old_stdout = g.stdOutIsRedirected() if not old_stderr: g.redirectStderr() if not old_stdout: g.redirectStdout() try: # execute all but the last 'block' if dbg: print('all but last') # exec '\n'.join(blocks[:-1]) in leo_globals, c.vs exec('\n'.join(blocks[:-1]), leo_globals, cvs) # Compatible with Python 3.x. all_done = False except SyntaxError: # splitting of the last block caused syntax error try: # is the whole thing a single expression? if dbg: print('one expression') ans = eval(txt, leo_globals, cvs) except SyntaxError: if dbg: print('statement block') # exec txt in leo_globals, c.vs exec(txt, leo_globals, cvs) # Compatible with Python 3.x. all_done = True # either way, the last block is used now if not all_done: # last block still needs using try: if dbg: print('final expression') ans = eval(blocks[-1], leo_globals, cvs) except SyntaxError: ans = None if dbg: print('final statement') # exec blocks[-1] in leo_globals, c.vs exec(blocks[-1], leo_globals, cvs) # Compatible with Python 3.x. if redirects: if not old_stderr: g.restoreStderr() if not old_stdout: g.restoreStdout() if ans is None: # see if last block was a simple "var =" assignment key = blocks[-1].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] if ans is None: # see if whole text was a simple /multi-line/ "var =" assignment key = blocks[0].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] cvs['_last'] = ans if ans is not None: # annoying to echo 'None' to the log during line by line execution txt = str(ans) lines = txt.split('\n') if len(lines) > 10: txt = '\n'.join(lines[:5] + ['<snip>'] + lines[-5:]) if len(txt) > 500: txt = txt[:500] + ' <truncated>' g.es(txt) return ans
def vs_eval(kwargs): """Execute the selected text, if any. Select next line of text. Tries hard to capture the result of from the last expression in the selected text:: import datetime today = datetime.date.today() will captue the value of ``today`` even though the last line is a statement, not an expression. Stores results in ``c.vs['_last']`` for insertion into body by ``vs-last`` or ``vs-last-pretty``. Removes common indentation (``textwrap.dedent()``) before executing, allowing execution of indented code. ``g``, ``c``, and ``p`` are available to executing code, assignments are made in the ``c.vs`` namespace and persist for the life of ``c``. """ c = kwargs['c'] vsc = get_vs(c) cvs = vsc.d txt = c.frame.body.getSelectedText() # select next line ready for next select/send cycle # copied from .../plugins/leoscreen.py b = c.frame.body.getAllText() i = c.frame.body.getInsertPoint() try: j = b[i:].index('\n')+i+1 c.frame.body.setSelectionRange(i,j) except ValueError: # no more \n in text c.frame.body.setSelectionRange(i,i) pass if not txt: return txt = textwrap.dedent(txt) blocks = re.split('\n(?=[^\\s])', txt) leo_globals = {'c':c, 'p':c.p, 'g':g} ans = None dbg = False redirects = c.config.getBool('valuespace_vs_eval_redirect') if redirects: old_stderr = g.stdErrIsRedirected() old_stdout = g.stdOutIsRedirected() if not old_stderr: g.redirectStderr() if not old_stdout: g.redirectStdout() try: # execute all but the last 'block' if dbg: print('all but last') # exec '\n'.join(blocks[:-1]) in leo_globals, c.vs exec('\n'.join(blocks[:-1]), leo_globals, cvs) # Compatible with Python 3.x. all_done = False except SyntaxError: # splitting of the last block caused syntax error try: # is the whole thing a single expression? if dbg: print('one expression') ans = eval(txt, leo_globals, cvs) except SyntaxError: if dbg: print('statement block') # exec txt in leo_globals, c.vs exec(txt, leo_globals, cvs) # Compatible with Python 3.x. all_done = True # either way, the last block is used now if not all_done: # last block still needs using try: if dbg: print('final expression') ans = eval(blocks[-1], leo_globals, cvs) except SyntaxError: ans = None if dbg: print('final statement') # exec blocks[-1] in leo_globals, c.vs exec(blocks[-1], leo_globals, cvs) # Compatible with Python 3.x. if redirects: if not old_stderr: g.restoreStderr() if not old_stdout: g.restoreStdout() if ans is None: # see if last block was a simple "var =" assignment key = blocks[-1].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] if ans is None: # see if whole text was a simple /multi-line/ "var =" assignment key = blocks[0].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] cvs['_last'] = ans if ans is not None: # annoying to echo 'None' to the log during line by line execution txt = str(ans) lines = txt.split('\n') if len(lines) > 10: txt = '\n'.join(lines[:5]+['<snip>']+lines[-5:]) if len(txt) > 500: txt = txt[:500] + ' <truncated>' g.es(txt)
def eval_text(c, txt): if not txt: return vsc = get_vs(c) cvs = vsc.d txt = textwrap.dedent(txt) blocks = re.split('\n(?=[^\\s])', txt) leo_globals = {'c':c, 'p':c.p, 'g':g} ans = None dbg = False redirects = c.config.getBool('valuespace_vs_eval_redirect') if redirects: old_stderr = g.stdErrIsRedirected() old_stdout = g.stdOutIsRedirected() if not old_stderr: g.redirectStderr() if not old_stdout: g.redirectStdout() try: # execute all but the last 'block' if dbg: print('all but last') # exec '\n'.join(blocks[:-1]) in leo_globals, c.vs exec('\n'.join(blocks[:-1]), leo_globals, cvs) # Compatible with Python 3.x. all_done = False except SyntaxError: # splitting of the last block caused syntax error try: # is the whole thing a single expression? if dbg: print('one expression') ans = eval(txt, leo_globals, cvs) except SyntaxError: if dbg: print('statement block') # exec txt in leo_globals, c.vs exec(txt, leo_globals, cvs) # Compatible with Python 3.x. all_done = True # either way, the last block is used now if not all_done: # last block still needs using try: if dbg: print('final expression') ans = eval(blocks[-1], leo_globals, cvs) except SyntaxError: ans = None if dbg: print('final statement') # exec blocks[-1] in leo_globals, c.vs exec(blocks[-1], leo_globals, cvs) # Compatible with Python 3.x. if redirects: if not old_stderr: g.restoreStderr() if not old_stdout: g.restoreStdout() if ans is None: # see if last block was a simple "var =" assignment key = blocks[-1].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] if ans is None: # see if whole text was a simple /multi-line/ "var =" assignment key = blocks[0].split('=', 1)[0].strip() if key in cvs: ans = cvs[key] cvs['_last'] = ans if ans is not None: # annoying to echo 'None' to the log during line by line execution txt = str(ans) lines = txt.split('\n') if len(lines) > 10: txt = '\n'.join(lines[:5]+['<snip>']+lines[-5:]) if len(txt) > 500: txt = txt[:500] + ' <truncated>' g.es(txt) return ans