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
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))
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: "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
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: '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
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
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()
def get_width(self, progress_bar): return fragment_list_width(self.text)
def get_width(self, progress_bar: 'ProgressBar') -> AnyDimension: return fragment_list_width(self.text)
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
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()