def _create_application(self): """ Create an `Application` instance. """ return Application( input=self.input, output=self.output, layout=create_layout( self, lexer=DynamicLexer( lambda: self._lexer if self.enable_syntax_highlighting else SimpleLexer()), input_buffer_height=self._input_buffer_height, extra_buffer_processors=self._extra_buffer_processors, extra_body=self._extra_layout_body, extra_toolbars=self._extra_toolbars), key_bindings=merge_key_bindings([ load_python_bindings(self), load_sidebar_bindings(self), load_confirm_exit_bindings(self), # Extra key bindings should not be active when the sidebar is visible. ConditionalKeyBindings( self.extra_key_bindings, Condition(lambda: not self.show_sidebar)) ]), color_depth=lambda: self.color_depth, paste_mode=Condition(lambda: self.paste_mode), mouse_support=Condition(lambda: self.enable_mouse_support), style=DynamicStyle(lambda: self._current_style), style_transformation=ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), filter=Condition(lambda: self.swap_light_and_dark)), include_default_pygments_style=False, reverse_vi_search_direction=True)
def test_swap_light_and_dark_style_transformation(): transformation = SwapLightAndDarkStyleTransformation() # Test with 6 digit hex colors. before = Attrs( color="440000", bgcolor="888844", bold=True, underline=True, strike=True, italic=True, blink=False, reverse=False, hidden=False, ) after = Attrs( color="ffbbbb", bgcolor="bbbb76", bold=True, underline=True, strike=True, italic=True, blink=False, reverse=False, hidden=False, ) assert transformation.transform_attrs(before) == after # Test with ANSI colors. before = Attrs( color="ansired", bgcolor="ansiblack", bold=True, underline=True, strike=True, italic=True, blink=False, reverse=False, hidden=False, ) after = Attrs( color="ansibrightred", bgcolor="ansiwhite", bold=True, underline=True, strike=True, italic=True, blink=False, reverse=False, hidden=False, ) assert transformation.transform_attrs(before) == after
def test_swap_light_and_dark_style_transformation(): transformation = SwapLightAndDarkStyleTransformation() # Test with 6 digit hex colors. before = Attrs(color='440000', bgcolor='888844', bold=True, underline=True, italic=True, blink=False, reverse=False, hidden=False) after = Attrs(color='ffbbbb', bgcolor='bbbb76', bold=True, underline=True, italic=True, blink=False, reverse=False, hidden=False) assert transformation.transform_attrs(before) == after # Test with ANSI colors. before = Attrs(color='ansired', bgcolor='ansiblack', bold=True, underline=True, italic=True, blink=False, reverse=False, hidden=False) after = Attrs(color='ansibrightred', bgcolor='ansiwhite', bold=True, underline=True, italic=True, blink=False, reverse=False, hidden=False) assert transformation.transform_attrs(before) == after
def _create_application(self, editing_mode, erase_when_done): """ Create the `Application` object. """ dyncond = self._dyncond # Default key bindings. auto_suggest_bindings = load_auto_suggest_bindings() open_in_editor_bindings = load_open_in_editor_bindings() prompt_bindings = self._create_prompt_bindings() # Create application application = Application( layout=self.layout, style=DynamicStyle(lambda: self.style), style_transformation=merge_style_transformations([ DynamicStyleTransformation(lambda: self.style_transformation), ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), dyncond('swap_light_and_dark_colors'), ), ]), include_default_pygments_style=dyncond( 'include_default_pygments_style'), clipboard=DynamicClipboard(lambda: self.clipboard), key_bindings=merge_key_bindings([ merge_key_bindings([ auto_suggest_bindings, ConditionalKeyBindings( open_in_editor_bindings, dyncond('enable_open_in_editor') & has_focus(DEFAULT_BUFFER)), prompt_bindings ]), DynamicKeyBindings(lambda: self.key_bindings), ]), mouse_support=dyncond('mouse_support'), editing_mode=editing_mode, erase_when_done=erase_when_done, reverse_vi_search_direction=True, color_depth=lambda: self.color_depth, # I/O. input=self.input, output=self.output) # During render time, make sure that we focus the right search control # (if we are searching). - This could be useful if people make the # 'multiline' property dynamic. ''' def on_render(app): multiline = _true(self.multiline) current_control = app.layout.current_control if multiline: if current_control == search_buffer_control: app.layout.current_control = search_toolbar.control app.invalidate() else: if current_control == search_toolbar.control: app.layout.current_control = search_buffer_control app.invalidate() app.on_render += on_render ''' return application
def __init__( self, get_globals=None, get_locals=None, history_filename=None, vi_mode=False, input=None, output=None, color_depth=None, # For internal use. extra_key_bindings=None, _completer=None, _validator=None, _lexer=None, _extra_buffer_processors=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None): self.get_globals = get_globals or (lambda: {}) self.get_locals = get_locals or self.get_globals self._completer = _completer or PythonCompleter( self.get_globals, self.get_locals) self._validator = _validator or PythonValidator( self.get_compiler_flags) self._lexer = _lexer or PygmentsLexer(PythonLexer) if history_filename: self.history = ThreadedHistory(FileHistory(history_filename)) else: self.history = InMemoryHistory() self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self.extra_key_bindings = extra_key_bindings or KeyBindings() # Settings. self.show_signature = False self.show_docstring = False self.show_meta_enter_message = True self.completion_visualisation = CompletionVisualisation.MULTI_COLUMN self.completion_menu_scroll_offset = 1 self.show_line_numbers = False self.show_status_bar = True self.wrap_lines = True self.complete_while_typing = True self.paste_mode = False # When True, don't insert whitespace after newline. self.confirm_exit = True # Ask for confirmation when Control-D is pressed. self.accept_input_on_enter = 2 # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. self.enable_open_in_editor = True self.enable_system_bindings = True self.enable_input_validation = True self.enable_auto_suggest = False self.enable_mouse_support = False self.enable_history_search = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.enable_syntax_highlighting = True self.swap_light_and_dark = False self.highlight_matching_parenthesis = False self.show_sidebar = False # Currently show the sidebar. self.show_sidebar_help = True # When the sidebar is visible, also show the help text. self.show_exit_confirmation = False # Currently show 'Do you really want to exit?' self.terminal_title = None # The title to be displayed in the terminal. (None or string.) self.exit_message = 'Do you really want to exit?' self.insert_blank_line_after_output = True # (For the REPL.) # The buffers. self.default_buffer = self._create_buffer() self.search_buffer = Buffer() self.docstring_buffer = Buffer(read_only=True) # Tokens to be shown at the prompt. self.prompt_style = 'classic' # The currently active style. self.all_prompt_styles = { # Styles selectable from the menu. 'ipython': IPythonPrompt(self), 'classic': ClassicPrompt(), } self.get_input_prompt = lambda: \ self.all_prompt_styles[self.prompt_style].in_prompt() self.get_output_prompt = lambda: \ self.all_prompt_styles[self.prompt_style].out_prompt() #: Load styles. self.code_styles = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name = 'default' self._current_ui_style_name = 'default' if is_windows(): self._current_code_style_name = 'win32' self._current_style = self._generate_style() self.color_depth = color_depth or ColorDepth.default() self.max_brightness = 1.0 self.min_brightness = 0.0 # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index = 0 #: Incremeting integer counting the current statement. self.current_statement_index = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures = [] # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running = False self.output = output or create_output() self.input = input or create_input(sys.stdin) self.style_transformation = merge_style_transformations([ ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), filter=Condition(lambda: self.swap_light_and_dark)), AdjustBrightnessStyleTransformation(lambda: self.min_brightness, lambda: self.max_brightness), ]) self.ptpython_layout = PtPythonLayout( self, lexer=DynamicLexer(lambda: self._lexer if self. enable_syntax_highlighting else SimpleLexer()), input_buffer_height=self._input_buffer_height, extra_buffer_processors=self._extra_buffer_processors, extra_body=self._extra_layout_body, extra_toolbars=self._extra_toolbars) self.app = self._create_application() if vi_mode: self.app.editing_mode = EditingMode.VI
def __init__(self, app): self.app = app self.payload_lexer = PeekLexer(stack=('value',)) self.style = style_from_pygments_cls(PeekStyle) self.style_transformation = ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), self.app.config.as_bool('swap_colour'))
def _create_app(self): """ Create `Application` instance for this . """ pymux = self.pymux def on_focus_changed(): """ When the focus changes to a read/write buffer, make sure to go to insert mode. This happens when the ViState was set to NAVIGATION in the copy buffer. """ vi_state = app.vi_state if app.current_buffer.read_only(): vi_state.input_mode = InputMode.NAVIGATION else: vi_state.input_mode = InputMode.INSERT app = Application( output=self.output, input=self.input, color_depth=self.color_depth, layout=Layout(container=self.layout_manager.layout), key_bindings=pymux.key_bindings_manager.key_bindings, mouse_support=Condition(lambda: pymux.enable_mouse_support), full_screen=True, style=self.pymux.style, style_transformation=ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), Condition(lambda: self.pymux.swap_dark_and_light), ), on_invalidate=(lambda _: pymux.invalidate())) # Synchronize the Vi state with the CLI object. # (This is stored in the current class, but expected to be in the # CommandLineInterface.) def sync_vi_state(_): VI = EditingMode.VI EMACS = EditingMode.EMACS if self.confirm_text or self.prompt_command or self.command_mode: app.editing_mode = VI if pymux.status_keys_vi_mode else EMACS else: app.editing_mode = VI if pymux.mode_keys_vi_mode else EMACS app.key_processor.before_key_press += sync_vi_state app.key_processor.after_key_press += sync_vi_state app.key_processor.after_key_press += self.sync_focus # Set render postpone time. (.1 instead of 0). # This small change ensures that if for a split second a process # outputs a lot of information, we don't give the highest priority to # rendering output. (Nobody reads that fast in real-time.) app.max_render_postpone_time = .1 # Second. # Hide message when a key has been pressed. def key_pressed(_): self.message = None app.key_processor.before_key_press += key_pressed # The following code needs to run with the application active. # Especially, `create_window` needs to know what the current # application is, in order to focus the new pane. with set_app(app): # Redraw all CLIs. (Adding a new client could mean that the others # change size, so everything has to be redrawn.) pymux.invalidate() pymux.startup() return app
def __init__( self, get_globals: Optional[_GetNamespace] = None, get_locals: Optional[_GetNamespace] = None, history_filename: Optional[str] = None, vi_mode: bool = False, color_depth: Optional[ColorDepth] = None, # Input/output. input: Optional[Input] = None, output: Optional[Output] = None, # For internal use. extra_key_bindings: Optional[KeyBindings] = None, _completer: Optional[Completer] = None, _validator: Optional[Validator] = None, _lexer: Optional[Lexer] = None, _extra_buffer_processors=None, _extra_layout_body=None, _extra_toolbars=None, _input_buffer_height=None, ) -> None: self.get_globals: _GetNamespace = get_globals or (lambda: {}) self.get_locals: _GetNamespace = get_locals or self.get_globals self._completer = _completer or FuzzyCompleter( PythonCompleter( self.get_globals, self.get_locals, lambda: self.enable_dictionary_completion, ), enable_fuzzy=Condition(lambda: self.enable_fuzzy_completion), ) self._validator = _validator or PythonValidator( self.get_compiler_flags) self._lexer = _lexer or PygmentsLexer(PythonLexer) self.history: History if history_filename: self.history = ThreadedHistory(FileHistory(history_filename)) else: self.history = InMemoryHistory() self._input_buffer_height = _input_buffer_height self._extra_layout_body = _extra_layout_body or [] self._extra_toolbars = _extra_toolbars or [] self._extra_buffer_processors = _extra_buffer_processors or [] self.extra_key_bindings = extra_key_bindings or KeyBindings() # Settings. self.title: AnyFormattedText = "" self.show_signature: bool = False self.show_docstring: bool = False self.show_meta_enter_message: bool = True self.completion_visualisation: CompletionVisualisation = CompletionVisualisation.MULTI_COLUMN self.completion_menu_scroll_offset: int = 1 self.show_line_numbers: bool = False self.show_status_bar: bool = True self.wrap_lines: bool = True self.complete_while_typing: bool = True self.paste_mode: bool = False # When True, don't insert whitespace after newline. self.confirm_exit: bool = True # Ask for confirmation when Control-D is pressed. self.accept_input_on_enter: int = 2 # Accept when pressing Enter 'n' times. # 'None' means that meta-enter is always required. self.enable_open_in_editor: bool = True self.enable_system_bindings: bool = True self.enable_input_validation: bool = True self.enable_auto_suggest: bool = False self.enable_mouse_support: bool = False self.enable_history_search: bool = False # When True, like readline, going # back in history will filter the # history on the records starting # with the current input. self.enable_syntax_highlighting: bool = True self.enable_fuzzy_completion: bool = False self.enable_dictionary_completion: bool = False self.swap_light_and_dark: bool = False self.highlight_matching_parenthesis: bool = False self.show_sidebar: bool = False # Currently show the sidebar. # When the sidebar is visible, also show the help text. self.show_sidebar_help: bool = True # Currently show 'Do you really want to exit?' self.show_exit_confirmation: bool = False # The title to be displayed in the terminal. (None or string.) self.terminal_title: Optional[str] = None self.exit_message: str = "Do you really want to exit?" self.insert_blank_line_after_output: bool = True # (For the REPL.) # The buffers. self.default_buffer = self._create_buffer() self.search_buffer: Buffer = Buffer() self.docstring_buffer: Buffer = Buffer(read_only=True) # Tokens to be shown at the prompt. self.prompt_style: str = "classic" # The currently active style. # Styles selectable from the menu. self.all_prompt_styles: Dict[str, PromptStyle] = { "ipython": IPythonPrompt(self), "classic": ClassicPrompt(), } self.get_input_prompt = lambda: self.all_prompt_styles[ self.prompt_style].in_prompt() self.get_output_prompt = lambda: self.all_prompt_styles[ self.prompt_style].out_prompt() #: Load styles. self.code_styles: Dict[str, BaseStyle] = get_all_code_styles() self.ui_styles = get_all_ui_styles() self._current_code_style_name: str = "default" self._current_ui_style_name: str = "default" if is_windows(): self._current_code_style_name = "win32" self._current_style = self._generate_style() self.color_depth: ColorDepth = color_depth or ColorDepth.default() self.max_brightness: float = 1.0 self.min_brightness: float = 0.0 # Options to be configurable from the sidebar. self.options = self._create_options() self.selected_option_index: int = 0 #: Incremeting integer counting the current statement. self.current_statement_index: int = 1 # Code signatures. (This is set asynchronously after a timeout.) self.signatures: List[Any] = [] # Boolean indicating whether we have a signatures thread running. # (Never run more than one at the same time.) self._get_signatures_thread_running: bool = False # Get into Vi navigation mode at startup self.vi_start_in_navigation_mode: bool = False # Preserve last used Vi input mode between main loop iterations self.vi_keep_last_used_mode: bool = False self.style_transformation = merge_style_transformations([ ConditionalStyleTransformation( SwapLightAndDarkStyleTransformation(), filter=Condition(lambda: self.swap_light_and_dark), ), AdjustBrightnessStyleTransformation(lambda: self.min_brightness, lambda: self.max_brightness), ]) self.ptpython_layout = PtPythonLayout( self, lexer=DynamicLexer(lambda: self._lexer if self. enable_syntax_highlighting else SimpleLexer()), input_buffer_height=self._input_buffer_height, extra_buffer_processors=self._extra_buffer_processors, extra_body=self._extra_layout_body, extra_toolbars=self._extra_toolbars, ) self.app = self._create_application(input, output) if vi_mode: self.app.editing_mode = EditingMode.VI