def setup_docstring_containers(repl): parent_container = get_ptpython_parent_container(repl) # the same as ptpython containers, but without signature checking parent_container.children.extend( [ ConditionalContainer( content=Window(height=Dimension.exact(1), char="\u2500", style="class:separator"), filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done, ), ConditionalContainer( content=Window( BufferControl(buffer=repl.docstring_buffer, lexer=PygmentsLexer(PythonLexer)), height=Dimension(max=12), ), filter=HasDocString(repl) & ShowDocstring(repl) & ~is_done, ), ] )
def create_layout(buffers, settings, key_bindings_manager, python_prompt_control=None, lexer=PythonLexer, extra_sidebars=None, extra_buffer_processors=None): D = LayoutDimension show_all_buffers = Condition(lambda cli: settings.show_all_buffers) extra_sidebars = extra_sidebars or [] extra_buffer_processors = extra_buffer_processors or [] def create_buffer_window(buffer_name): def menu_position(cli): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = cli.buffers[buffer_name] if b.complete_state is None and b.signatures: row, col = b.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer_name=buffer_name, lexer=lexer, show_line_numbers=ShowLineNumbersFilter(settings, buffer_name), input_processors=[BracketsMismatchProcessor()] + extra_buffer_processors, menu_position=menu_position, ), # As long as we're editing, prefer a minimal height of 8. get_height=(lambda cli: (None if cli.is_done else D(min=6))), # When done, show only if this was focussed. filter=(~IsDone() & show_all_buffers) | PythonBufferFocussed(buffer_name, settings)) def create_buffer_window_separator(buffer_name): return Window(width=D.exact(1), content=FillControl('\u2502', token=Token.Separator), filter=~IsDone() & show_all_buffers) buffer_windows = [] for b in sorted(buffers): if b.startswith('python-'): buffer_windows.append(create_buffer_window_separator(b)) buffer_windows.append(create_buffer_window(b)) return HSplit([ VSplit([ HSplit([ TabsToolbar(settings), FloatContainer(content=HSplit([ VSplit([ Window( python_prompt_control, dont_extend_width=True, ), VSplit(buffer_windows), ]), ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=12, extra_filter=ShowCompletionsMenu( settings))), Float(xcursor=True, ycursor=True, content=SignatureToolbar(settings)) ]), ArgToolbar(), SearchToolbar(), SystemToolbar(), ValidationToolbar(), CompletionsToolbar( extra_filter=ShowCompletionsToolbar(settings)), # Docstring region. Window(height=D.exact(1), content=FillControl('\u2500', token=Token.Separator), filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone()), Window( BufferControl( buffer_name='docstring', default_token=Token.Docstring, #lexer=PythonLexer, ), filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone(), height=D(max=12), ), ]), ] + extra_sidebars + [ PythonSidebar(settings, key_bindings_manager), ]), VSplit([ PythonToolbar(key_bindings_manager, settings), ShowSidebarButtonInfo(), ]) ])
def create_layout(settings, key_bindings_manager, python_prompt_control=None, lexer=PythonLexer, extra_sidebars=None, extra_buffer_processors=None): D = LayoutDimension extra_sidebars = extra_sidebars or [] extra_buffer_processors = extra_buffer_processors or [] def create_python_input_window(): def menu_position(cli): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = cli.buffers['default'] if b.complete_state is None and settings.signatures: row, col = settings.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer_name=DEFAULT_BUFFER, lexer=lexer, show_line_numbers=ShowLineNumbersFilter(settings, 'default'), input_processors=[ # Show matching parentheses, but only while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()), HighlightSearchProcessor(preview_search=Always()), HighlightSelectionProcessor()] + extra_buffer_processors, menu_position=menu_position, # Make sure that we always see the result of an reverse-i-search: preview_search=Always(), ), # As long as we're editing, prefer a minimal height of 6. get_height=(lambda cli: (None if cli.is_done else D(min=6))), ) return HSplit([ VSplit([ HSplit([ FloatContainer( content=HSplit([ VSplit([ Window( python_prompt_control, dont_extend_width=True, ), create_python_input_window(), ]), ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=12, extra_filter=ShowCompletionsMenu(settings))), Float(xcursor=True, ycursor=True, content=SignatureToolbar(settings)) ]), ArgToolbar(), SearchToolbar(), SystemToolbar(), ValidationToolbar(), CompletionsToolbar(extra_filter=ShowCompletionsToolbar(settings)), # Docstring region. Window(height=D.exact(1), content=FillControl('\u2500', token=Token.Separator), filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone()), Window( BufferControl( buffer_name='docstring', default_token=Token.Docstring, #lexer=PythonLexer, ), filter=HasSignature(settings) & ShowDocstring(settings) & ~IsDone(), height=D(max=12), ), ]), ] + extra_sidebars + [ PythonSidebar(settings, key_bindings_manager), ]), VSplit([ PythonToolbar(key_bindings_manager, settings), ShowSidebarButtonInfo(), ]) ])
def __init__( self, get_globals=None, get_locals=None, stdin=None, stdout=None, vi_mode=False, history_filename=None, style=PythonStyle, # For internal use. _completer=None, _validator=None, _python_prompt_control=None, _extra_buffers=None, _extra_sidebars=None): self.settings = PythonCLISettings() 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.history = FileHistory( history_filename) if history_filename else History() self.python_prompt_control = _python_prompt_control or PythonPrompt( self.settings) self._extra_sidebars = _extra_sidebars or [] # Use a KeyBindingManager for loading the key bindings. self.key_bindings_manager = KeyBindingManager( enable_vi_mode=vi_mode, enable_system_prompt=True) load_python_bindings( self.key_bindings_manager, self.settings, add_buffer=self.add_new_python_buffer, close_current_buffer=self.close_current_python_buffer) self.get_signatures_thread_running = False buffers = { 'default': Buffer(focussable=AlwaysOff() ), # Never use or focus the default buffer. 'docstring': Buffer(focussable=HasSignature(self.settings) & ShowDocstring(self.settings)), # XXX: also make docstring read only. } buffers.update(_extra_buffers or {}) self.cli = CommandLineInterface( style=style, key_bindings_registry=self.key_bindings_manager.registry, buffers=buffers, create_async_autocompleters=True) def on_input_timeout(): """ When there is no input activity, in another thread, get the signature of the current code. """ if not self.cli.focus_stack.current.startswith('python-'): return # Never run multiple get-signature threads. if self.get_signatures_thread_running: return self.get_signatures_thread_running = True buffer = self.cli.current_buffer document = buffer.document def run(): script = get_jedi_script_from_document(document, self.get_locals(), self.get_globals()) # Show signatures in help text. if script: try: signatures = script.call_signatures() except ValueError: # e.g. in case of an invalid \\x escape. signatures = [] except Exception: # Sometimes we still get an exception (TypeError), because # of probably bugs in jedi. We can silence them. # See: https://github.com/davidhalter/jedi/issues/492 signatures = [] else: signatures = [] self.get_signatures_thread_running = False # Set signatures and redraw if the text didn't change in the # meantime. Otherwise request new signatures. if buffer.text == document.text: buffer.signatures = signatures # Set docstring in docstring buffer. if signatures: string = signatures[0].docstring() if not isinstance(string, six.text_type): string = string.decode('utf-8') self.cli.buffers['docstring'].reset( initial_document=Document(string, cursor_position=0)) else: self.cli.buffers['docstring'].reset() self.cli.request_redraw() else: on_input_timeout() self.cli.run_in_executor(run) self.cli.onInputTimeout += on_input_timeout self.cli.onReset += self.key_bindings_manager.reset self.add_new_python_buffer()
def create_layout(python_input, key_bindings_manager, lexer=PythonLexer, extra_body=None, extra_toolbars=None, extra_buffer_processors=None, input_buffer_height=None): D = LayoutDimension extra_body = [extra_body] if extra_body else [] extra_toolbars = extra_toolbars or [] extra_buffer_processors = extra_buffer_processors or [] input_buffer_height = input_buffer_height or D(min=6) def create_python_input_window(): def menu_position(cli): """ When there is no autocompletion menu to be shown, and we have a signature, set the pop-up position at `bracket_start`. """ b = cli.buffers[DEFAULT_BUFFER] if b.complete_state is None and python_input.signatures: row, col = python_input.signatures[0].bracket_start index = b.document.translate_row_col_to_index(row - 1, col) return index return Window( BufferControl( buffer_name=DEFAULT_BUFFER, lexer=lexer, input_processors=[ # Show matching parentheses, but only while editing. ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() & Condition(lambda cli: python_input.highlight_matching_parenthesis)), ConditionalProcessor( processor=HighlightSearchProcessor(preview_search=Always()), filter=HasFocus(SEARCH_BUFFER)), HighlightSelectionProcessor(), ConditionalProcessor( processor=AppendAutoSuggestion(), filter=~IsDone()) ] + extra_buffer_processors, menu_position=menu_position, wrap_lines=Condition(lambda cli: python_input.wrap_lines), # Make sure that we always see the result of an reverse-i-search: preview_search=Always(), ), left_margins=[PromptMargin(python_input)], # Scroll offsets. The 1 at the bottom is important to make sure the # cursor is never below the "Press [Meta+Enter]" message which is a float. scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4), # As long as we're editing, prefer a minimal height of 6. get_height=(lambda cli: ( None if cli.is_done or python_input.show_exit_confirmation else input_buffer_height)), ) return HSplit([ VSplit([ HSplit([ FloatContainer( content=HSplit( [create_python_input_window()] + extra_body ), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( scroll_offset=Integer.from_callable( lambda: python_input.completion_menu_scroll_offset), max_height=12, extra_filter=show_completions_menu(python_input))), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=show_multi_column_completions_menu(python_input))), Float(xcursor=True, ycursor=True, content=signature_toolbar(python_input)), Float(left=2, bottom=1, content=exit_confirmation(python_input)), Float(bottom=0, right=0, height=1, content=meta_enter_message(python_input)), Float(bottom=1, left=1, right=0, content=python_sidebar_help(python_input)), ]), ArgToolbar(), SearchToolbar(), SystemToolbar(), ValidationToolbar(), CompletionsToolbar(extra_filter=show_completions_toolbar(python_input)), # Docstring region. ConditionalContainer( content=Window(height=D.exact(1), content=FillControl('\u2500', token=Token.Separator)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone()), ConditionalContainer( content=Window( BufferControl( buffer_name='docstring', lexer=SimpleLexer(default_token=Token.Docstring), #lexer=PythonLexer, ), height=D(max=12)), filter=HasSignature(python_input) & ShowDocstring(python_input) & ~IsDone(), ), ]), HSplit([ python_sidebar(python_input), python_sidebar_navigation(python_input), ]) ]), ] + extra_toolbars + [ VSplit([ status_bar(key_bindings_manager, python_input), show_sidebar_button_info(python_input), ]) ])