|
1 | | -import code |
2 | 1 | import contextlib |
3 | 2 | import errno |
4 | 3 | import functools |
|
17 | 16 | from pygments import format |
18 | 17 | from bpython._py3compat import PythonLexer |
19 | 18 | from pygments.formatters import TerminalFormatter |
20 | | -from interpreter import Interp |
21 | 19 |
|
22 | 20 | import blessings |
23 | 21 |
|
|
45 | 43 | from bpython.curtsiesfrontend import events as bpythonevents |
46 | 44 | from bpython.curtsiesfrontend.parse import parse as bpythonparse |
47 | 45 | from bpython.curtsiesfrontend.parse import func_for_letter, color_for_letter |
| 46 | +from bpython.curtsiesfrontend.preprocess import indent_empty_lines |
| 47 | +from bpython.curtsiesfrontend.interpreter import Interp, code_finished_will_parse |
48 | 48 |
|
49 | 49 | #TODO other autocomplete modes (also fix in other bpython implementations) |
50 | 50 |
|
@@ -457,7 +457,7 @@ def process_control_event(self, e): |
457 | 457 | if ctrl_char is not None: |
458 | 458 | return self.process_event(ctrl_char) |
459 | 459 | simple_events = just_simple_events(e.events) |
460 | | - source = bad_empty_lines_removed(''.join(simple_events)) |
| 460 | + source = indent_empty_lines(''.join(simple_events), self.interp.compile) |
461 | 461 |
|
462 | 462 | with self.in_paste_mode(): |
463 | 463 | for ee in source: |
@@ -713,7 +713,7 @@ def send_session_to_external_editor(self, filename=None): |
713 | 713 | text = self.send_to_external_editor(for_editor) |
714 | 714 | lines = text.split('\n') |
715 | 715 | from_editor = [line for line in lines if line[:4] != '### '] |
716 | | - source = bad_empty_lines_removed('\n'.join(from_editor)) |
| 716 | + source = indent_empty_lines('\n'.join(from_editor), self.interp.compile) |
717 | 717 | self.history = source.split('\n') |
718 | 718 | self.reevaluate(insert_into_history=True) |
719 | 719 | self.current_line = lines[-1][4:] |
@@ -828,7 +828,8 @@ def push(self, line, insert_into_history=True): |
828 | 828 | code_to_run = '\n'.join(self.buffer) |
829 | 829 |
|
830 | 830 | logger.debug('running %r in interpreter', self.buffer) |
831 | | - c, code_will_parse = code_finished_will_parse('\n'.join(self.buffer)) |
| 831 | + c, code_will_parse = code_finished_will_parse('\n'.join(self.buffer), |
| 832 | + self.interp.compile) |
832 | 833 | self.saved_predicted_parse_error = not code_will_parse |
833 | 834 | if c: |
834 | 835 | logger.debug('finished - buffer cleared') |
@@ -1429,63 +1430,6 @@ def just_simple_events(event_list): |
1429 | 1430 | simple_events.append(e) |
1430 | 1431 | return simple_events |
1431 | 1432 |
|
1432 | | -def code_finished_will_parse(s): |
1433 | | - """Returns a tuple of whether the buffer could be complete and whether it will parse |
1434 | | -
|
1435 | | - True, True means code block is finished and no predicted parse error |
1436 | | - True, False means code block is finished because a parse error is predicted |
1437 | | - False, True means code block is unfinished |
1438 | | - False, False isn't possible - an predicted error makes code block done""" |
1439 | | - try: |
1440 | | - finished = bool(code.compile_command(s)) |
1441 | | - code_will_parse = True |
1442 | | - except (ValueError, SyntaxError, OverflowError): |
1443 | | - finished = True |
1444 | | - code_will_parse = False |
1445 | | - return finished, code_will_parse |
1446 | | - |
1447 | | -def bad_empty_lines_removed(s): |
1448 | | - """Removes empty lines that would cause unfinished input to be evaluated""" |
1449 | | - # If there's a syntax error followed by an empty line, remove the empty line |
1450 | | - lines = s.split('\n') |
1451 | | - #TODO this should be our interpreter object making this decision so it |
1452 | | - # can be compiler directive (__future__ statement) -aware |
1453 | | - #TODO specifically catch IndentationErrors instead of any syntax errors |
1454 | | - |
1455 | | - current_block = [] |
1456 | | - complete_blocks = [] |
1457 | | - for i, line in enumerate(s.split('\n')): |
1458 | | - current_block.append(line) |
1459 | | - could_be_finished, valid = code_finished_will_parse('\n'.join(current_block)) |
1460 | | - if could_be_finished and valid: |
1461 | | - complete_blocks.append(current_block) |
1462 | | - current_block = [] |
1463 | | - continue |
1464 | | - elif could_be_finished and not valid: |
1465 | | - if complete_blocks: |
1466 | | - complete_blocks[-1].extend(current_block) |
1467 | | - current_block = complete_blocks.pop() |
1468 | | - if len(current_block) < 2: |
1469 | | - return s #TODO return partial result instead of giving up |
1470 | | - last_line = current_block.pop(len(current_block) - 2) |
1471 | | - assert not last_line, last_line |
1472 | | - new_finished, new_valid = code_finished_will_parse('\n'.join(current_block)) |
1473 | | - if new_valid and new_finished: |
1474 | | - complete_blocks.append(current_block) |
1475 | | - current_block = [] |
1476 | | - elif new_valid: |
1477 | | - continue |
1478 | | - else: |
1479 | | - return s #TODO return partial result instead of giving up |
1480 | | - |
1481 | | - else: |
1482 | | - return s #TODO return partial result instead of giving up |
1483 | | - else: |
1484 | | - continue |
1485 | | - return '\n'.join(['\n'.join(block) |
1486 | | - for block in complete_blocks + [current_block] |
1487 | | - if block]) |
1488 | | - |
1489 | 1433 |
|
1490 | 1434 | #TODO this needs some work to function again and be useful for embedding |
1491 | 1435 | def simple_repl(): |
|
0 commit comments