示例#1
0
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
示例#2
0
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)
示例#3
0
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