(self, orig_s)
| 633 | |
| 634 | # Subclasses of Repl need to implement echo, current_line, cw |
| 635 | def echo(self, orig_s): |
| 636 | s = orig_s.rstrip("\n") |
| 637 | if s: |
| 638 | if self.current_output is None: |
| 639 | self.current_output = urwid.Text(("output", s)) |
| 640 | if self.edit is None: |
| 641 | self.listbox.body.append(self.current_output) |
| 642 | # Focus the widget we just added to force the |
| 643 | # listbox to scroll. This causes output to scroll |
| 644 | # if the user runs a blocking call that prints |
| 645 | # more than a screenful, instead of staying |
| 646 | # scrolled to the previous input line and then |
| 647 | # jumping to the bottom when done. |
| 648 | self.listbox.set_focus(len(self.listbox.body) - 1) |
| 649 | else: |
| 650 | self.listbox.body.insert(-1, self.current_output) |
| 651 | # The edit widget should be focused and *stay* focused. |
| 652 | # XXX TODO: make sure the cursor stays in the same spot. |
| 653 | self.listbox.set_focus(len(self.listbox.body) - 1) |
| 654 | else: |
| 655 | # XXX this assumes this all has "output" markup applied. |
| 656 | self.current_output.set_text( |
| 657 | ("output", self.current_output.text + s) |
| 658 | ) |
| 659 | if orig_s.endswith("\n"): |
| 660 | self.current_output = None |
| 661 | |
| 662 | # If we hit this repeatedly in a loop the redraw is rather |
| 663 | # slow (testcase: pprint(__builtins__). So if we have recently |
| 664 | # drawn the screen already schedule a call in the future. |
| 665 | # |
| 666 | # Unfortunately we may hit this function repeatedly through a |
| 667 | # blocking call triggered by the user, in which case our |
| 668 | # timeout will not run timely as we do not return to urwid's |
| 669 | # eventloop. So we manually check if our timeout has long |
| 670 | # since expired, and redraw synchronously if it has. |
| 671 | if self._redraw_handle is None: |
| 672 | self.main_loop.draw_screen() |
| 673 | |
| 674 | def maybe_redraw(loop, self): |
| 675 | if self._redraw_pending: |
| 676 | loop.draw_screen() |
| 677 | self._redraw_pending = False |
| 678 | |
| 679 | self._redraw_handle = None |
| 680 | |
| 681 | self._redraw_handle = self.main_loop.set_alarm_in( |
| 682 | self._time_between_redraws, maybe_redraw, self |
| 683 | ) |
| 684 | self._redraw_time = time.time() |
| 685 | else: |
| 686 | self._redraw_pending = True |
| 687 | now = time.time() |
| 688 | if now - self._redraw_time > 2 * self._time_between_redraws: |
| 689 | # The timeout is well past expired, assume we're |
| 690 | # blocked and redraw synchronously. |
| 691 | self.main_loop.draw_screen() |
| 692 | self._redraw_time = now |
no test coverage detected