Beispiel #1
 def keyboard_interrupt(self):
     #TODO factor out the common cleanup from running a line
     self.cursor_offset_in_line = -1
     self.display_lines.extend(paint.display_linize(self.current_cursor_line, self.width))
     self.display_lines.extend(paint.display_linize("KeyboardInterrupt", self.width))
Beispiel #2
 def send_to_stdout(self, output):
     lines = output.split('\n')
     logging.debug('display_lines: %r', self.display_lines)
     self.current_stdouterr_line += lines[0]
     if len(lines) > 1:
         self.display_lines.extend(paint.display_linize(self.current_stdouterr_line, self.width, blank_line=True))
         self.display_lines.extend(sum([paint.display_linize(line, self.width, blank_line=True) for line in lines[1:-1]], []))
         self.current_stdouterr_line = lines[-1]
     logging.debug('display_lines: %r', self.display_lines)
Beispiel #3
 def send_to_stdin(self, line):
     if line.endswith('\n'):
         self.display_lines.extend(paint.display_linize(self.current_output_line, self.width))
         self.current_output_line = ''
     #self.display_lines = self.display_lines[:len(self.display_lines) - self.stdin.old_num_lines]
     #lines = paint.display_linize(line, self.width)
     #self.stdin.old_num_lines = len(lines)
     #self.display_lines.extend(paint.display_linize(line, self.width))
Beispiel #4
 def display_buffer_lines(self):
     """The display lines (wrapped, colored, with prompts) for the current buffer"""
     lines = []
     for display_line in self.display_buffer:
         display_line = (func_for_letter(self.config.color_scheme['prompt_more'])(self.ps2)
                        if lines else
                        func_for_letter(self.config.color_scheme['prompt'])(self.ps1)) + display_line
         for line in paint.display_linize(display_line, self.width):
     return lines
Beispiel #5
    def run_code_and_maybe_finish(self, for_code=None):
        r = self.coderunner.run_code(for_code=for_code)
        if r:
            logging.debug("----- Running finish command stuff -----")
            logging.debug("saved_indent: %r", self.saved_indent)
            err = self.saved_predicted_parse_error
            self.saved_predicted_parse_error = False

            indent = self.saved_indent
            if err:
                indent = 0

            #TODO This should be printed ABOVE the error that just happened instead
            # or maybe just thrown away and not shown
            if self.current_stdouterr_line:
                self.display_lines.extend(paint.display_linize(self.current_stdouterr_line, self.width))
                self.current_stdouterr_line = ''

            self._current_line = ' '*indent
            self.cursor_offset_in_line = len(self._current_line)
Beispiel #6
    def paint(self, about_to_exit=False, user_quit=False):
        """Returns an array of min_height or more rows and width columns, plus cursor position

        Paints the entire screen - ideally the terminal display layer will take a diff and only
        write to the screen in portions that have changed, but the idea is that we don't need
        to worry about that here, instead every frame is completely redrawn because
        less state is cool!
        # The hairiest function in the curtsies - a cleanup would be great.

        if about_to_exit:
            self.clean_up_current_line_for_exit() # exception to not changing state!

        width, min_height = self.width, self.height
        show_status_bar = bool(self.status_bar._message) or (self.config.curtsies_fill_terminal or self.status_bar.has_focus)
        if show_status_bar:
            min_height -= 1

        current_line_start_row = len(self.lines_for_display) - max(0, self.scroll_offset)
        if self.request_paint_to_clear_screen: # or show_status_bar and about_to_exit ?
            self.request_paint_to_clear_screen = False
            if self.config.curtsies_fill_terminal: #TODO clean up this logic - really necessary check?
                arr = FSArray(self.height - 1 + current_line_start_row, width)
                arr = FSArray(self.height + current_line_start_row, width)
            arr = FSArray(0, width)
        #TODO test case of current line filling up the whole screen (there aren't enough rows to show it)

        if current_line_start_row < 0: #if current line trying to be drawn off the top of the screen
            logging.debug('#<---History contiguity broken by rewind--->')
            msg = "#<---History contiguity broken by rewind--->"
            arr[0, 0:min(len(msg), width)] = [msg[:width]]

            # move screen back up a screen minus a line
            while current_line_start_row < 0:
                self.scroll_offset = self.scroll_offset - self.height
                current_line_start_row = len(self.lines_for_display) - max(-1, self.scroll_offset)

            history = paint.paint_history(max(0, current_line_start_row - 1), width, self.lines_for_display)
            arr[1:history.height+1,:history.width] = history

            if arr.height <= min_height:
                arr[min_height, 0] = ' ' # force scroll down to hide broken history message
            history = paint.paint_history(current_line_start_row, width, self.lines_for_display)
            arr[:history.height,:history.width] = history

        current_line = paint.paint_current_line(min_height, width, self.current_cursor_line)
        if user_quit: # quit() or exit() in interp
            current_line_start_row = current_line_start_row - current_line.height
        logging.debug("---current line row slice %r, %r", current_line_start_row, current_line_start_row + current_line.height)
        logging.debug("---current line col slice %r, %r", 0, current_line.width)
        arr[current_line_start_row:current_line_start_row + current_line.height,
            0:current_line.width] = current_line

        if current_line.height > min_height:
            return arr, (0, 0) # short circuit, no room for infobox

        lines = paint.display_linize(self.current_cursor_line+'X', width)
                                       # extra character for space for the cursor
        current_line_end_row = current_line_start_row + len(lines) - 1

        if self.stdin.has_focus:
            cursor_row, cursor_column = divmod(len(self.current_stdouterr_line) + self.stdin.cursor_offset_in_line, width)
            assert cursor_column >= 0, cursor_column
        elif self.coderunner.running: #TODO does this ever happen?
            cursor_row, cursor_column = divmod(len(self.current_cursor_line) + self.cursor_offset_in_line, width)
            assert cursor_column >= 0, (cursor_column, len(self.current_cursor_line), len(self._current_line), self.cursor_offset_in_line)
            cursor_row, cursor_column = divmod(len(self.current_cursor_line) - len(self._current_line) + self.cursor_offset_in_line, width)
            assert cursor_column >= 0, (cursor_column, len(self.current_cursor_line), len(self._current_line), self.cursor_offset_in_line)
        cursor_row += current_line_start_row

        if self.list_win_visible:
            logging.debug('infobox display code running')
            visible_space_above = history.height
            visible_space_below = min_height - current_line_end_row - 1

            info_max_rows = max(visible_space_above, visible_space_below)
            infobox = paint.paint_infobox(info_max_rows, int(width * self.config.cli_suggestion_width), self.matches, self.argspec, self.current_word, self.docstring, self.config)

            if visible_space_above >= infobox.height and self.config.curtsies_list_above:
                arr[current_line_start_row - infobox.height:current_line_start_row, 0:infobox.width] = infobox
                arr[current_line_end_row + 1:current_line_end_row + 1 + infobox.height, 0:infobox.width] = infobox
                logging.debug('slamming infobox of shape %r into arr of shape %r', infobox.shape, arr.shape)

        logging.debug('about to exit: %r', about_to_exit)
        if show_status_bar:
            if self.config.curtsies_fill_terminal:
                if about_to_exit:
                    arr[max(arr.height, min_height), :] = FSArray(1, width)
                    arr[max(arr.height, min_height), :] = paint.paint_statusbar(1, width, self.status_bar.current_line, self.config)

                    if self.presentation_mode:
                        rows = arr.height
                        columns = arr.width
                        last_key_box = paint.paint_last_events(rows, columns, [events.pp_event(x) for x in self.last_events if x])
                        arr[arr.height-last_key_box.height:arr.height, arr.width-last_key_box.width:arr.width] = last_key_box
                statusbar_row = min_height + 1 if arr.height == min_height else arr.height
                if about_to_exit:
                    arr[statusbar_row, :] = FSArray(1, width)
                    arr[statusbar_row, :] = paint.paint_statusbar(1, width, self.status_bar.current_line, self.config)

        if self.config.color_scheme['background'] not in ('d', 'D'):
            for r in range(arr.height):
                arr[r] = fmtstr(arr[r], bg=color_for_letter(self.config.color_scheme['background']))
        logging.debug('returning arr of size %r', arr.shape)
        logging.debug('cursor pos: %r', (cursor_row, cursor_column))
        return arr, (cursor_row, cursor_column)
Beispiel #7
 def send_to_stderr(self, error):
                                for line in sum([paint.display_linize(line, self.width)
                                                 for line in error.split('\n')], [])])