Пример #1
0
    def format_output(self, result):
        locals: Dict[str, Any] = self.get_locals()
        locals["_"] = locals["_%i" % self.current_statement_index] = result

        if result is None:
            return None
        else:
            out_prompt = self.get_output_prompt()

            try:
                result_str = "%r\n" % (result, )
            except UnicodeDecodeError:
                # In Python 2: `__repr__` should return a bytestring,
                # so to put it in a unicode context could raise an
                # exception that the 'ascii' codec can't decode certain
                # characters. Decode as utf-8 in that case.
                result_str = "%s\n" % repr(result).decode(  # type: ignore
                    "utf-8")

            # Align every line to the first one.
            line_sep = "\n" + " " * fragment_list_width(out_prompt)
            result_str = line_sep.join(result_str.splitlines()).strip("")

            # Write output tokens.
            if self.enable_syntax_highlighting:
                formatted_output = FormattedText(
                    merge_formatted_text([
                        out_prompt,
                        PygmentsTokens(list(_lex_python_result(result_str))),
                    ])())
                formatted_output.pop()
            else:
                formatted_output = FormattedText(out_prompt +
                                                 [("", result_str)])
            return formatted_output
Пример #2
0
def show_sidebar_button_info(python_input):
    """
    Create `Layout` for the information in the right-bottom corner.
    (The right part of the status bar.)
    """
    @if_mousedown
    def toggle_sidebar(mouse_event):
        " Click handler for the menu. "
        python_input.show_sidebar = not python_input.show_sidebar

    version = sys.version_info
    tokens = [
        ('class:status-toolbar.key', '[F2]', toggle_sidebar),
        ('class:status-toolbar', ' Menu', toggle_sidebar),
        ('class:status-toolbar', ' - '),
        ('class:status-toolbar.python-version',
         '%s %i.%i.%i' % (platform.python_implementation(), version[0],
                          version[1], version[2])),
        ('class:status-toolbar', ' '),
    ]
    width = fragment_list_width(tokens)

    def get_text_fragments():
        # Python version
        return tokens

    return ConditionalContainer(
        content=Window(FormattedTextControl(get_text_fragments),
                       style='class:status-toolbar',
                       height=Dimension.exact(1),
                       width=Dimension.exact(width)),
        filter=~is_done & renderer_height_is_known
        & Condition(lambda: python_input.show_status_bar and not python_input.
                    show_exit_confirmation))
Пример #3
0
    def get_width(self, progress_bar):
        if self.width:
            return self.width

        all_labels = [self._add_suffix(c.label) for c in progress_bar.counters]
        if all_labels:
            max_widths = max(fragment_list_width(l) for l in all_labels)
            return D(preferred=max_widths, max=max_widths)
        else:
            return D()
    def get_width(self, progress_bar):
        if self.width:
            return self.width

        all_labels = [self._add_suffix(c.label) for c in progress_bar.counters]
        if all_labels:
            max_widths = max(fragment_list_width(l) for l in all_labels)
            return D(preferred=max_widths, max=max_widths)
        else:
            return D()
Пример #5
0
 def get_width(self, progress_bar: "Progress") -> AnyDimension:
     all_values = [
         self.get_render_text(c) for c in progress_bar.models
         if isinstance(c, PlayerModel)
     ]
     if all_values:
         max_widths = max(
             fragment_list_width(to_formatted_text(v, ''))
             for v in all_values)
         return max_widths
     return 0
Пример #6
0
    def format(self, progress_bar, progress, width):
        label = self._add_suffix(progress.label)
        cwidth = fragment_list_width(label)

        if cwidth > width:
            # It doesn't fit -> scroll task name.
            label = explode_text_fragments(label)
            max_scroll = cwidth - width
            current_scroll = int(time.time() * 3 % max_scroll)
            label = label[current_scroll:]

        return label
    def format(self, progress_bar, progress, width):
        label = self._add_suffix(progress.label)
        cwidth = fragment_list_width(label)

        if cwidth > width:
            # It doesn't fit -> scroll task name.
            label = explode_text_fragments(label)
            max_scroll = cwidth - width
            current_scroll = int(time.time() * 3 % max_scroll)
            label = label[current_scroll:]

        return label
Пример #8
0
    def format(self, progress_bar: 'ProgressBar',
               progress: 'ProgressBarCounter', width: int) -> AnyFormattedText:

        label = self._add_suffix(progress.label)
        cwidth = fragment_list_width(label)

        if cwidth > width:
            # It doesn't fit -> scroll task name.
            label = explode_text_fragments(label)
            max_scroll = cwidth - width
            current_scroll = int(time.time() * 3 % max_scroll)
            label = label[current_scroll:]

        return label
Пример #9
0
    def get_height_for_line(
        self,
        lineno: int,
        width: int,
        get_line_prefix: Optional[GetLinePrefixCallable],
        slice_stop: Optional[int] = None,
    ) -> int:
        """
        Return the height that a given line would need if it is rendered in a
        space with the given width (using line wrapping).

        :param get_line_prefix: None or a `Window.get_line_prefix` callable
            that returns the prefix to be inserted before this line.
        :param slice_stop: Wrap only "line[:slice_stop]" and return that
            partial result. This is needed for scrolling the window correctly
            when line wrapping.
        :returns: The computed height.
        """
        # Instead of using `get_line_prefix` as key, we use render_counter
        # instead. This is more reliable, because this function could still be
        # the same, while the content would change over time.
        key = get_app().render_counter, lineno, width, slice_stop

        try:
            return self._line_heights_cache[key]
        except KeyError:
            if width == 0:
                height = 10**8
            else:
                # Calculate line width first.
                line = fragment_list_to_text(
                    self.get_line(lineno))[:slice_stop]
                text_width = get_cwidth(line)

                if get_line_prefix:
                    # Add prefix width.
                    text_width += fragment_list_width(
                        to_formatted_text(get_line_prefix(lineno, 0)))

                    # Slower path: compute path when there's a line prefix.
                    height = 1

                    # Keep wrapping as long as the line doesn't fit.
                    # Keep adding new prefixes for every wrapped line.
                    while text_width > width:
                        height += 1
                        text_width -= width

                        fragments2 = to_formatted_text(
                            get_line_prefix(lineno, height - 1))
                        prefix_width = get_cwidth(
                            fragment_list_to_text(fragments2))

                        if prefix_width >= width:  # Prefix doesn't fit.
                            height = 10**8
                            break

                        text_width += prefix_width
                else:
                    # Fast path: compute height when there's no line prefix.
                    try:
                        quotient, remainder = divmod(text_width, width)
                    except ZeroDivisionError:
                        height = 10**8
                    else:
                        if remainder:
                            quotient += 1  # Like math.ceil.
                        height = max(1, quotient)

            # Cache and return
            self._line_heights_cache[key] = height
            return height
Пример #10
0
def patched_execute(self, line):
    """
    Evaluate the line and print the result.
    """
    output = self.app.output

    # WORKAROUND: Due to a bug in Jedi, the current directory is removed
    # from sys.path. See: https://github.com/davidhalter/jedi/issues/1148
    if "" not in sys.path:
        sys.path.insert(0, "")

    def compile_with_flags(code, mode):
        " Compile code with the right compiler flags. "
        return compile(code, "<stdin>", mode, flags=self.get_compiler_flags(), dont_inherit=True)

    if line.lstrip().startswith("\x1a"):
        # When the input starts with Ctrl-Z, quit the REPL.
        self.app.exit()

    elif line.lstrip().startswith("!"):
        # Run as shell command
        os.system(line[1:])
    else:
        # Try eval first
        try:
            code = compile_with_flags(line, "eval")
            result = eval(code, self.get_globals(), self.get_locals())

            locals = self.get_locals()
            locals["_"] = locals["_%i" % self.current_statement_index] = result

            if result is not None:
                out_prompt = self.get_output_prompt()

                try:
                    result_str = "%r\n" % (result,)
                except UnicodeDecodeError:
                    # In Python 2: `__repr__` should return a bytestring,
                    # so to put it in a unicode context could raise an
                    # exception that the 'ascii' codec can't decode certain
                    # characters. Decode as utf-8 in that case.
                    result_str = "%s\n" % repr(result).decode("utf-8")

                # Align every line to the first one.
                line_sep = "\n" + " " * fragment_list_width(out_prompt)
                result_str = line_sep.join(result_str.splitlines()) + "\n"

                # Support ansi formatting (removed syntax higlighting)
                ansi_formatted = ANSI(result_str)._formatted_text
                formatted_output = merge_formatted_text([FormattedText(out_prompt) + ansi_formatted])

                print_formatted_text(
                    formatted_output,
                    style=self._current_style,
                    style_transformation=self.style_transformation,
                    include_default_pygments_style=False,
                )

        # If not a valid `eval` expression, run using `exec` instead.
        except SyntaxError:
            code = compile_with_flags(line, "exec")
            six.exec_(code, self.get_globals(), self.get_locals())

        output.flush()
Пример #11
0
 def get_width(self, progress_bar):
     return fragment_list_width(self.text)
Пример #12
0
 def get_width(self, progress_bar: 'ProgressBar') -> AnyDimension:
     return fragment_list_width(self.text)
Пример #13
0
    def _execute(self, line):
        """
        Evaluate the line and print the result.
        """
        output = self.app.output

        def compile_with_flags(code, mode):
            " Compile code with the right compiler flags. "
            return compile(code,
                           '<stdin>',
                           mode,
                           flags=self.get_compiler_flags(),
                           dont_inherit=True)

        if line.lstrip().startswith('\x1a'):
            # When the input starts with Ctrl-Z, quit the REPL.
            self.app.exit()

        elif line.lstrip().startswith('!'):
            # Run as shell command
            os.system(line[1:])
        else:
            # Try eval first
            try:
                code = compile_with_flags(line, 'eval')
                result = eval(code, self.get_globals(), self.get_locals())

                locals = self.get_locals()
                locals['_'] = locals['_%i' %
                                     self.current_statement_index] = result

                if result is not None:
                    out_prompt = self.get_output_prompt()

                    try:
                        result_str = '%r\n' % (result, )
                    except UnicodeDecodeError:
                        # In Python 2: `__repr__` should return a bytestring,
                        # so to put it in a unicode context could raise an
                        # exception that the 'ascii' codec can't decode certain
                        # characters. Decode as utf-8 in that case.
                        result_str = '%s\n' % repr(result).decode('utf-8')

                    # Align every line to the first one.
                    line_sep = '\n' + ' ' * fragment_list_width(out_prompt)
                    result_str = line_sep.join(result_str.splitlines()) + '\n'

                    # Write output tokens.
                    if self.enable_syntax_highlighting:
                        formatted_output = merge_formatted_text([
                            out_prompt,
                            PygmentsTokens(list(
                                _lex_python_result(result_str))),
                        ])
                    else:
                        formatted_output = FormattedText(out_prompt +
                                                         [('', result_str)])

                    print_formatted_text(formatted_output,
                                         style=self._current_style,
                                         include_default_pygments_style=False)

            # If not a valid `eval` expression, run using `exec` instead.
            except SyntaxError:
                code = compile_with_flags(line, 'exec')
                six.exec_(code, self.get_globals(), self.get_locals())

            output.flush()
    def get_height_for_line(
            self, lineno: int, width: int,
            get_line_prefix: Optional[GetLinePrefixCallable],
            slice_stop: Optional[int] = None) -> int:
        """
        Return the height that a given line would need if it is rendered in a
        space with the given width (using line wrapping).

        :param get_line_prefix: None or a `Window.get_line_prefix` callable
            that returns the prefix to be inserted before this line.
        :param slice_stop: Wrap only "line[:slice_stop]" and return that
            partial result. This is needed for scrolling the window correctly
            when line wrapping.
        :returns: The computed height.
        """
        # Instead of using `get_line_prefix` as key, we use render_counter
        # instead. This is more reliable, because this function could still be
        # the same, while the content would change over time.
        key = get_app().render_counter, lineno, width, slice_stop

        try:
            return self._line_heights_cache[key]
        except KeyError:
            if width == 0:
                height = 10 ** 8
            else:
                # Calculate line width first.
                line = fragment_list_to_text(self.get_line(lineno))[:slice_stop]
                text_width = get_cwidth(line)

                if get_line_prefix:
                    # Add prefix width.
                    text_width += fragment_list_width(
                        to_formatted_text(get_line_prefix(lineno, 0)))

                    # Slower path: compute path when there's a line prefix.
                    height = 1

                    # Keep wrapping as long as the line doesn't fit.
                    # Keep adding new prefixes for every wrapped line.
                    while text_width > width:
                        height += 1
                        text_width -= width

                        fragments2 = to_formatted_text(
                            get_line_prefix(lineno, height - 1))
                        prefix_width = get_cwidth(fragment_list_to_text(fragments2))

                        if prefix_width >= width:  # Prefix doesn't fit.
                            height = 10 ** 8
                            break

                        text_width += prefix_width
                else:
                    # Fast path: compute height when there's no line prefix.
                    try:
                        quotient, remainder = divmod(text_width, width)
                    except ZeroDivisionError:
                        height = 10 ** 8
                    else:
                        if remainder:
                            quotient += 1  # Like math.ceil.
                        height = max(1, quotient)

            # Cache and return
            self._line_heights_cache[key] = height
            return height
Пример #15
0
    def _execute(self, line):
        """
        Evaluate the line and print the result.
        """
        output = self.app.output

        # WORKAROUND: Due to a bug in Jedi, the current directory is removed
        # from sys.path. See: https://github.com/davidhalter/jedi/issues/1148
        if '' not in sys.path:
            sys.path.insert(0, '')

        def compile_with_flags(code, mode):
            " Compile code with the right compiler flags. "
            return compile(code, '<stdin>', mode,
                           flags=self.get_compiler_flags(),
                           dont_inherit=True)

        if line.lstrip().startswith('\x1a'):
            # When the input starts with Ctrl-Z, quit the REPL.
            self.app.exit()

        elif line.lstrip().startswith('!'):
            # Run as shell command
            os.system(line[1:])
        else:
            # Try eval first
            try:
                code = compile_with_flags(line, 'eval')
                result = eval(code, self.get_globals(), self.get_locals())

                locals = self.get_locals()
                locals['_'] = locals['_%i' % self.current_statement_index] = result

                if result is not None:
                    out_prompt = self.get_output_prompt()

                    try:
                        result_str = '%r\n' % (result, )
                    except UnicodeDecodeError:
                        # In Python 2: `__repr__` should return a bytestring,
                        # so to put it in a unicode context could raise an
                        # exception that the 'ascii' codec can't decode certain
                        # characters. Decode as utf-8 in that case.
                        result_str = '%s\n' % repr(result).decode('utf-8')

                    # Align every line to the first one.
                    line_sep = '\n' + ' ' * fragment_list_width(out_prompt)
                    result_str = line_sep.join(result_str.splitlines()) + '\n'

                    # Write output tokens.
                    if self.enable_syntax_highlighting:
                        formatted_output = merge_formatted_text([
                            out_prompt,
                            PygmentsTokens(list(_lex_python_result(result_str))),
                        ])
                    else:
                        formatted_output = FormattedText(
                                out_prompt + [('', result_str)])

                    print_formatted_text(
                        formatted_output, style=self._current_style,
                        style_transformation=self.style_transformation,
                        include_default_pygments_style=False)

            # If not a valid `eval` expression, run using `exec` instead.
            except SyntaxError:
                code = compile_with_flags(line, 'exec')
                six.exec_(code, self.get_globals(), self.get_locals())

            output.flush()
 def get_width(self, progress_bar):
     return fragment_list_width(self.text)