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(cli, mouse_event): " Click handler for the menu. " python_input.show_sidebar = not python_input.show_sidebar token = Token.Toolbar.Status version = sys.version_info tokens = [ (token.Key, '[F2]', toggle_sidebar), (token, ' Menu', toggle_sidebar), (token, ' - '), (token.PythonVersion, '%s %i.%i.%i' % (platform.python_implementation(), version[0], version[1], version[2])), (token, ' '), ] width = token_list_width(tokens) def get_tokens(cli): # Python version return tokens return ConditionalContainer( content=Window( TokenListControl(get_tokens, default_char=Char(token=token)), height=LayoutDimension.exact(1), width=LayoutDimension.exact(width)), filter=~IsDone() & RendererHeightIsKnown() & Condition(lambda cli: python_input.show_status_bar and not python_input.show_exit_confirmation))
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(cli, mouse_event): " Click handler for the menu. " python_input.show_sidebar = not python_input.show_sidebar token = Token.Toolbar.Status version = sys.version_info tokens = [ (token.Key, '[F2]', toggle_sidebar), (token, ' Menu', toggle_sidebar), (token, ' - '), (token.PythonVersion, '%s %i.%i.%i' % (platform.python_implementation(), version[0], version[1], version[2])), (token, ' '), ] width = token_list_width(tokens) def get_tokens(cli): # Python version return tokens return ConditionalContainer( content=Window( TokenListControl(get_tokens, default_char=Char(token=token)), height=LayoutDimension.exact(1), width=LayoutDimension.exact(width)), filter=~IsDone() & RendererHeightIsKnown() & Condition(lambda cli: python_input.show_status_bar and not python_input.show_exit_confirmation))
def __init__(self, python_input): token = Token.Toolbar.Status version = sys.version_info tokens = [ (token, ' [F2] Options'), (token, ' - '), (token.PythonVersion, '%s %i.%i.%i' % (platform.python_implementation(), version[0], version[1], version[2])), (token, ' '), ] width = token_list_width(tokens) def get_tokens(cli): # Python version return tokens super(ShowSidebarButtonInfo, self).__init__( content=Window( TokenListControl(get_tokens, default_char=Char(token=token)), height=LayoutDimension.exact(1), width=LayoutDimension.exact(width)), filter=~IsDone() & RendererHeightIsKnown() & Condition(lambda cli: python_input.show_status_bar and not python_input.show_exit_confirmation))
def _execute(self, cli, line): """ Evaluate the line and print the result. """ output = cli.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. cli.set_return_value(None) 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_tokens = [ (Token.Out, 'Out['), (Token.Out.Number, '%s' % self.current_statement_index), (Token.Out, ']:'), (Token, ' '), ] 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' + ' ' * token_list_width(out_tokens) result_str = line_sep.join(result_str.splitlines()) + '\n' # Write output tokens. out_tokens.extend(_lex_python_result(result_str)) cli.print_tokens(out_tokens) # 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.write('\n') output.flush()
def _execute(self, cli, line): """ Evaluate the line and print the result. """ output = cli.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. cli.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_tokens = self.get_output_prompt_tokens(cli) 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' + ' ' * token_list_width(out_tokens) result_str = line_sep.join(result_str.splitlines()) + '\n' # Write output tokens. out_tokens.extend(_lex_python_result(result_str)) cli.print_tokens(out_tokens) # 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.write('\n') output.flush()
def __init__(self): token = Token.Toolbar.Status version = sys.version_info tokens = [ (token, ' [F2] Sidebar'), (token, ' - '), (token.PythonVersion, '%s %i.%i.%i' % (platform.python_implementation(), version[0], version[1], version[2])), (token, ' '), ] width = token_list_width(tokens) def get_tokens(cli): # Python version return tokens super(ShowSidebarButtonInfo, self).__init__( TokenListControl(get_tokens, default_char=Char(token=token)), filter=~IsDone() & RendererHeightIsKnown(), height=LayoutDimension.exact(1), width=LayoutDimension.exact(width))
def _width(self): return token_list_width(self.in_prompt_tokens())
def create_layout(lexer=None, reserve_space_for_menu=8, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, extra_input_processors=None, multiline=False, wrap_lines=True): """ Creates a custom `Layout` for the Crash input REPL This layout includes: * a bottom left-aligned session toolbar container * a bottom right-aligned side-bar container +-------------------------------------------+ | cr> select 1; | | | | | +-------------------------------------------+ | bottom_toolbar_tokens sidebar_tokens | +-------------------------------------------+ """ # Create processors list. input_processors = [ ConditionalProcessor( # Highlight the reverse-i-search buffer HighlightSearchProcessor(preview_search=True), HasFocus(SEARCH_BUFFER)), ] if extra_input_processors: input_processors.extend(extra_input_processors) lexer = PygmentsLexer(lexer, sync_from_start=True) multiline = to_cli_filter(multiline) sidebar_token = [ (Token.Toolbar.Status.Key, "[ctrl+d]"), (Token.Toolbar.Status, " Exit") ] sidebar_width = token_list_width(sidebar_token) get_sidebar_tokens = lambda _: sidebar_token def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: buff = cli.current_buffer # Reserve the space, either when there are completions, or when # `complete_while_typing` is true and we expect completions very # soon. if buff.complete_while_typing() or buff.complete_state is not None: return LayoutDimension(min=reserve_space_for_menu) return LayoutDimension() # Create and return Container instance. return HSplit([ VSplit([ HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ Window( BufferControl( input_processors=input_processors, lexer=lexer, # enable preview search for reverse-i-search preview_search=True), get_height=get_height, wrap_lines=wrap_lines, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation tokens. ConditionalMargin( PromptMargin(get_prompt_tokens), filter=multiline ) ], ), ]), [ # Completion menu Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=HasFocus(DEFAULT_BUFFER)) ), ] ), # reverse-i-search toolbar (ctrl+r) ConditionalContainer(SearchToolbar(), multiline), ]) ]), ] + [ VSplit([ # Left-Aligned Session Toolbar ConditionalContainer( Window( TokenListControl(get_bottom_toolbar_tokens), height=LayoutDimension.exact(1) ), filter=~IsDone() & RendererHeightIsKnown()), # Right-Aligned Container ConditionalContainer( Window( TokenListControl(get_sidebar_tokens), height=LayoutDimension.exact(1), width=LayoutDimension.exact(sidebar_width) ), filter=~IsDone() & RendererHeightIsKnown()) ]) ])
def _width(self): return token_list_width(self.in_prompt_tokens())
def create_layout(message='', lexer=None, reserve_space_for_menu=8, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, extra_input_processors=None, multiline=False, wrap_lines=True): # Create processors list. input_processors = [ ConditionalProcessor( # Highlight the reverse-i-search buffer HighlightSearchProcessor(preview_search=True), HasFocus(SEARCH_BUFFER)), ] if extra_input_processors: input_processors.extend(extra_input_processors) lexer = PygmentsLexer(lexer, sync_from_start=True) multiline = to_cli_filter(multiline) sidebar_token = [(Token.Toolbar.Status.Key, "[ctrl+d]"), (Token.Toolbar.Status, " Exit")] sidebar_width = token_list_width(sidebar_token) get_prompt_tokens = lambda _: [(Token.Prompt, message)] get_sidebar_tokens = lambda _: sidebar_token def get_height(cli): # If there is an autocompletion menu to be shown, make sure that our # layout has at least a minimal height in order to display it. if reserve_space_for_menu and not cli.is_done: buff = cli.current_buffer # Reserve the space, either when there are completions, or when # `complete_while_typing` is true and we expect completions very # soon. if buff.complete_while_typing() or buff.complete_state is not None: return LayoutDimension(min=reserve_space_for_menu) return LayoutDimension() # Create and return Container instance. return HSplit([ VSplit([ HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ Window( BufferControl( input_processors=input_processors, lexer=lexer, # enable preview search for reverse-i-search preview_search=True), get_height=get_height, wrap_lines=wrap_lines, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation tokens. ConditionalMargin(PromptMargin( get_prompt_tokens), filter=multiline) ], ), ]), [ # Completion menu Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1, extra_filter=HasFocus( DEFAULT_BUFFER))), ]), # reverse-i-search toolbar (ctrl+r) ConditionalContainer(SearchToolbar(), multiline), ]) ]), ] + [ VSplit([ # Left-Aligned Session Toolbar ConditionalContainer(Window(TokenListControl( get_bottom_toolbar_tokens), height=LayoutDimension.exact(1)), filter=~IsDone() & RendererHeightIsKnown()), # Right-Aligned Container ConditionalContainer(Window(TokenListControl(get_sidebar_tokens), height=LayoutDimension.exact(1), width=LayoutDimension.exact( sidebar_width)), filter=~IsDone() & RendererHeightIsKnown()) ]) ])