async def async_show_results_select_dialog(): loop = asyncio.get_event_loop() auth = HTTPBasicAuth(registered_team_name, registered_auth_token) response = await loop.run_in_executor( None, lambda: requests.get("http://" + host + "/submissions/list", auth=auth)) if response.status_code != 200: output_field.text = "Failed to fetch submissions information.\nReason:\n{}".format(cleanhtml(response.text)) return data = response.json() results_select.values = [ (s["submission_no"], "{} {}".format( s["name"], s["submission_state"]) ) for s in data] submission_options.values.append(("None", "None")) flt = Float(content=results_select_dialog) layout.focus(results_select_dialog) root_container.floats.append(flt) output_field.text = ""
def __init__(self, event): def ok_handler(): # if len(ButtonManager.buttons) > 0: delete_server(event, name) root_container.floats.pop() def cancel_handler(): root_container.floats.pop() event.app.layout.focus(ButtonManager.prev_button) # Get data about server currently editing name = ButtonManager.current_button # Dialog configuration ok_button = Button(text='OK', handler=ok_handler) cancel_button = Button(text='Cancel', handler=cancel_handler) self.dialog = Dialog( title='Delete confirmation', body=Label( text='Are you sure you want to delete {}?'.format(name)), buttons=[cancel_button, ok_button], width=D(preferred=80), with_background=True) root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def __init__(self): self.no_action_dialog = NoActionDialog( ok_btn_cb=self.kb_run_action_or_dismiss) self.key_bindings = self._init_keybindings() tasks = [ Task('task1, summary', "Longer description", "lightblue", action=OpenOrStart('https://github.com/')), Task('task2, summary', "Longer description", "orange"), Task('task3, summary', "Longer description", "lightgreen"), Task('task4, summary', "Longer description", "darkred"), Task('task5, summary', "Longer description", "gray"), Task('task6, summary', "Longer description", "darkmagenta"), ] self.tasklist = TaskList( tasks, default_action=lambda t: self.no_action_dialog.show()) layout = Layout( FloatContainer(content=self.tasklist, floats=[Float(self.no_action_dialog)])) style = Style([]) super().__init__(layout, style, key_bindings=self.key_bindings, full_screen=True)
def __init__(self, buffer, **kwargs): self.buffer = buffer self.before_input_text = kwargs.get("before_input_text", "➜ ") self.title = kwargs.get("title", "COMMAND SHELL") self._buffer = buffer self._buffer_control = BufferControl( buffer=self.buffer, input_processors=[BeforeInput(text=self.before_input_text)], focus_on_click=True, ) self.window = Frame( title=self.title, key_bindings=self.kbindings(), body=FloatContainer( content=Window(self._buffer_control), key_bindings=None, floats=[ Float( xcursor=True, ycursor=True, content=CompletionsMenu(max_height=5, scroll_offset=1), ) ], ), height=3, )
def __init__(self, event, dialog): def ok_handler(): root_container.floats.pop() db.update_one(values={'name': name, 'auth': None}) event.app.layout.focus(ButtonManager.prev_button) select_item(event) def cancel_handler(): root_container.floats.pop() root_container.floats.append(self.auth_float) event.app.layout.focus(dialog) ok_button = Button(text='OK', handler=ok_handler) cancel_button = Button(text='Cancel', handler=cancel_handler) name = ButtonManager.current_button self.dialog = Dialog( title='Delete confirmation', body=Label( text='Are you sure you want to delete authentication for {}?'. format(name)), buttons=[cancel_button, ok_button], width=D(preferred=80), with_background=True) self.auth_float = root_container.floats.pop() root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def __init__(self, event, auth): super().__init__() self.event = event self.authtype = 'digest' authuser = auth.get('user', '') authpass = auth.get('password', '') self.authuser.text = authuser self.authuser.buffer.document = Document(authuser, len(authuser)) self.authpass_one.text = authpass self.authpass_one.buffer.document = Document(authpass, len(authpass)) self.authpass_two.text = authpass self.authpass_two.buffer.document = Document(authpass, len(authpass)) self.dialog = Dialog( title='Digest Authentication', body=HSplit([ Label(text='Username:\n'), self.authuser, Window(height=1, char=' '), Label(text='Password'), self.authpass_one, Window(height=1, char=' '), Label(text='Retype password'), self.authpass_two ]), buttons=[self.ok_button, self.cancel_button, self.delete_button], width=D(preferred=80), with_background=True, modal=True) root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def __init__(self, event, title='', text=''): def ok_handler(): root_container.floats.pop() # If there was an original dialog, insert it back into layout if self.orig_dialog: root_container.floats.append(self.orig_dialog) event.app.layout.focus(root_container.float_container) else: event.app.layout.focus(ButtonManager.prev_button) ok_button = Button(text='OK', handler=ok_handler) dialog = Dialog(Window(wrap_lines=True, content=FormattedTextControl(text=text), always_hide_cursor=True), title=title, width=D(preferred=80), buttons=[ok_button], with_background=True) try: # If a dialog was already up, save it self.orig_dialog = root_container.floats.pop() except IndexError: self.orig_dialog = None root_container.floats.append(Float(content=dialog)) event.app.layout.focus(ok_button)
def __init__(self, event=None, title='', text=''): content = Window(height=3, align=WindowAlign.CENTER, content=FormattedTextControl(text=text, show_cursor=False, modal=True)) body = HSplit([ Window(height=1, char=' '), content, Window(height=1, char=' '), ], padding=1) dialog = Dialog(body, title=title, width=D(preferred=80), with_background=True) loading_float = Float(content=dialog) root_container.floats.append(loading_float) self.focus = event.app.layout.focus self.focus(content)
def make_app(path_to_checklist, new_session): session = ChecklistSession(path_to_checklist, new_session) checklist = session.load() def status_bar_text(): items = checklist.items() return "{name} : {checked}/{total} done | 'q': quit | 'z': undo | '?' help | <up>/<down> moves | <space> toggles".format( name=checklist.name, checked=len([i for i in items if i.checked]), total=len(items)) checklist_window = Window(ChecklistControl(checklist, session), left_margins=[NumberedMargin()], right_margins=[ ScrollbarMargin(display_arrows=True), ]) status_bar_window = Window(content=FormattedTextControl(status_bar_text), height=1, style='reverse') root_container = FloatContainer( content=HSplit([ checklist_window, status_bar_window, ]), floats=[], ) if session.duplicates: root_container.floats.append( Float(content=DuplicatesWarningDialog(session.duplicates))) return Application(layout=Layout(root_container), full_screen=True, key_bindings=build_key_bindings())
def add_floating_screen(self, screen: Screen) -> None: """Add a screen to the layout as a floating window. Args: screen: The screen to add. """ root_container = screen.get_root_container() self.app.layout.container.floats.append(Float(root_container)) self.app.layout.focus(root_container)
def show_submission_dialog(): dir_path = os.getcwd() submission_options.values = [ (obj, obj) for obj in os.listdir(dir_path) if os.path.isfile(obj) and obj[-3:] == ".py" ] submission_options.values.append(("None", "None")) flt = Float(content=submission_dialog) layout.focus(submission_dialog) root_container.floats.append(flt)
def create(self): self.display_layout = display_container.create() completions = Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)) self.float_container = FloatContainer(content=self.display_layout, floats=[completions]) return Layout(HSplit([self.float_container]), focused_element=self.display_layout)
def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_bottom_toolbar_tokens=None): """ Generate default layout. """ assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens) # Create processors list. input_processors = [HighlightSearchProcessor(), HighlightSelectionProcessor()] if is_password: input_processors.extend([PasswordProcessor(), DefaultPrompt(message)]) else: input_processors.append(DefaultPrompt(message)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone())] else: toolbars = [] 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: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=Always()), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus(DEFAULT_BUFFER))) ] ), ValidationToolbar(), SystemToolbar(), ] + toolbars)
async def show_dialog_as_float(dialog): " Coroutine. " float_ = Float(content=dialog) root_container.floats.insert(0, float_) focused_before = app.layout.current_window app.layout.focus(dialog) result = await dialog.future app.layout.focus(focused_before) if float_ in root_container.floats: root_container.floats.remove(float_) return result
def __init__(self, editor, manager, window_arrangement): self.editor = editor # Back reference to editor. self.manager = manager self.window_arrangement = window_arrangement # Mapping from (`window_arrangement.Window`, `EditorBuffer`) to a frame # (Layout instance). # We keep this as a cache in order to easily reuse the same frames when # the layout is updated. (We don't want to create new frames on every # update call, because that way, we would loose some state, like the # vertical scroll offset.) self._frames = {} self._fc = FloatContainer( content=VSplit([ Window(BufferControl()) # Dummy window ]), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=12, scroll_offset=2, extra_filter=~HasFocus(COMMAND_BUFFER))), Float(content=BufferListOverlay(editor), bottom=1, left=0), Float(bottom=1, left=0, right=0, height=1, content=CompletionsToolbar( extra_filter=HasFocus(COMMAND_BUFFER) & ~bufferlist_overlay_visible_filter & Condition(lambda cli: editor.show_wildmenu))), Float(bottom=1, left=0, right=0, height=1, content=ValidationToolbar()), Float(bottom=1, left=0, right=0, height=1, content=MessageToolbarBar(editor)), Float(content=WelcomeMessageWindow(editor), height=WELCOME_MESSAGE_HEIGHT, width=WELCOME_MESSAGE_WIDTH), ] ) self.layout = FloatContainer( content=HSplit([ TabsToolbar(editor), self._fc, CommandLine(), ReportMessageToolbar(editor), SystemToolbar(), SearchToolbar(vi_mode=True), ]), floats=[ Float(right=0, height=1, bottom=0, width=5, content=SimpleArgToolbar()), ] )
def create_default_layout(message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_bottom_toolbar_tokens=None): """ Generate default layout. """ assert get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens) # Create processors list. if is_password: input_processors = [PasswordProcessor(), DefaultPrompt(message)] else: input_processors = [DefaultPrompt(message)] # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1), filter=~IsDone())] else: toolbars = [] 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: return LayoutDimension(min=8) else: return LayoutDimension() # Create and return Layout instance. return HSplit([ FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, extra_filter=HasFocus('default'))) ] ), ValidationToolbar(), SystemToolbar(), ] + toolbars)
def _get_layout(self): menu_layout = self._current_menu.get_layout() if self._current_menu.is_framed: menu_layout = Frame(menu_layout, title=self.header_string) if self._float_message_layout: menu_layout = FloatContainer( content=menu_layout, floats=[ Float( content=self._float_message_layout ) ] ) return menu_layout
def main(): # Create a big layout of many text areas, then wrap them in a `ScrollablePane`. root_container = VSplit([ Label("<left column>"), HSplit([ Label("ScrollContainer Demo"), Frame( ScrollablePane( HSplit([ Frame( TextArea( text=f"label-{i}", completer=animal_completer, )) for i in range(20) ])), ), ]), ]) root_container = FloatContainer( root_container, floats=[ Float( xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1), ), ], ) layout = Layout(container=root_container) # Key bindings. kb = KeyBindings() @kb.add("c-c") def exit(event) -> None: get_app().exit() kb.add("tab")(focus_next) kb.add("s-tab")(focus_previous) # Create and run application. application = Application(layout=layout, key_bindings=kb, full_screen=True, mouse_support=True) application.run()
def select_menu(items, display_format=None, max_height=10): """ Presents a list of options and allows the user to select one. This presents a static list of options and prompts the user to select one. This is similar to a completion menu but is different in that it does not allow a user to type and the returned value is always a member of the list. :type items: list :param list: The list of items to be selected from. If this list contains elements that are not strings the display_format option must be specified. :type display_format: Callable[[Any], str] :param display_format: A callable that takes a single element from the items list as input and returns a string used to represent the item in the menu. :type max_height: int :param max_height: The max number of items to show in the list at a time. :returns: The selected element from the items list. """ app_bindings = KeyBindings() @app_bindings.add('c-c') def exit_app(event): event.app.exit(exception=KeyboardInterrupt, style='class:aborting') min_height = min(max_height, len(items)) menu_window = Window( SelectionMenuControl(items, display_format=display_format), always_hide_cursor=False, height=Dimension(min=min_height, max=min_height), scroll_offsets=ScrollOffsets(), right_margins=[ScrollbarMargin()], ) # Using a FloatContainer was the only way I was able to succesfully # limit the height and width of the window. content = FloatContainer( Window(height=Dimension(min=min_height, max=min_height)), [Float(menu_window, top=0, left=0)]) app = Application( layout=Layout(content), key_bindings=app_bindings, erase_when_done=True, ) return app.run()
def get_layout(self) -> Layout: root_container = HSplit([ self._get_main_title_layout(), self._get_columns_layout(), self._get_main_content_layout(), Window(width=2, height=1, char="."), self.__bottom.get_input_instructions_view() ]) root_container = FloatContainer( root_container, floats=[ Float( xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1), ), ], ) return Layout(container=root_container)
def __init__(self, event): input_clock = get_current_alarm() def button_handler(): root_container.float_container.floats.pop() event.app.layout.focus(root_container.display_layout) clock.append(self.clock.text) reload_display_layout_clock() self.clock = TextArea(multiline=False, text=input_clock) self.clock.buffer.document = Document(input_clock, len(input_clock)) self.dialog = Dialog( title="Set New Alarm", body=HSplit([Label(text="you can set a new alarm clock here:\n", dont_extend_height=True), self.clock]), buttons=[Button(text="OK", handler=button_handler)] ) root_container.float_container.floats.append(Float(content=self.dialog)) event.app.layout.focus(self.dialog)
def create_app(self, focus): ctx = self.ctx ctx.cmd_buffer.on_text_changed += self.process_key ctx.input_buffer.on_text_changed += self.process_key ctx.cmd_buffer.cursor_position = len(ctx.cmd_buffer.text) if focus: focused_element = { "COMMAND": ctx.cmd_buffer, "c": ctx.cmd_buffer, "INPUT": ctx.input_buffer, "i": ctx.input_buffer, "OUTPUT": ctx.output_buffer, "o": ctx.output_buffer, }[focus] else: focused_element = ctx.cmd_buffer if ctx.input_buffer.text else ctx.input_buffer layout = Layout( FloatContainer( HSplit( [ self.create_boxes(), self.create_status_bar(), self.create_cmd_bar(), ] ), floats=[ Float(self.create_help()), ], ), focused_element=focused_element, ) return Application( key_bindings=kb, editing_mode=EditingMode.VI, clipboard=PyperclipClipboard(), color_depth=ColorDepth.from_env() or ColorDepth.DEPTH_24_BIT, full_screen=True, mouse_support=True, include_default_pygments_style=False, style=application_style, layout=layout, )
def create(self): sort_by = SortOrder.sort_by order = SortOrder.order self.body = titled_body.create(sort_by=sort_by, order=order) self.container = HSplit([self.body]) completions = Float(xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1)) self.float_container = FloatContainer(content=self.container, floats=[completions]) self.floats = self.float_container.floats return self.float_container
async def get_input(self, title: str = "", hide: bool = False) -> str: try: # Create a new Future. fut = self.LOOP.create_future() def finish(_buf: Buffer) -> bool: fut.set_result(_buf.text) return False # Create a Buffer, and assign its Handler to set the Result of the # Future created above. buf = Buffer(accept_handler=finish, multiline=False) self.floating_elems[:] = [ Float( Frame( Window( BufferControl( buf, input_processors=[ PasswordProcessor(), BeforeInput(" "), ] if hide else [BeforeInput(" ")], ), get_horizontal_scroll=(lambda *_: 0), ), title=title, ), width=35, height=3, ) ] self._app.layout.focus(buf) # Open a popup Float, and wait for the Future to be fulfilled. self.redraw() return await fut finally: self._app.layout.focus(self.command_buffer) self.floating_elems.clear()
def input_parser(buff): global update_announcements_enabled global update_leaderboard_enabled global block_backtick loop = asyncio.get_event_loop() text = input_field.text text = text.strip() if text == "announcements" or text == "a": stop_screens() update_announcements_enabled = True loop.create_task(update_announcements()) return elif text == "clear" or text == "help" or text == "c": stop_screens() output_field.text = help_text elif text == "registration" or text == "register": stop_screens() block_backtick = True flt = Float(content=registration_dialog) layout.focus(registration_dialog) root_container.floats.append(flt) elif text == "submit" or text == "s": stop_screens() block_backtick = True show_submission_dialog() layout.focus(submission_options) elif text == "leaderboard" or text == "l": stop_screens() update_leaderboard_enabled = True loop.create_task(update_leaderboard()) elif text == "results" or text == "r": stop_screens() block_backtick = True show_results_select_dialog()
def _create_layout(self): """ Create `Layout` for this prompt. """ dyncond = self._dyncond # Create functions that will dynamically split the prompt. (If we have # a multiline prompt.) has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \ _split_multiline_prompt(self._get_prompt) default_buffer = self.default_buffer search_buffer = self.search_buffer # Create processors list. all_input_processors = [ HighlightIncrementalSearchProcessor(), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), has_focus(default_buffer) & ~is_done), ConditionalProcessor(PasswordProcessor(), dyncond('is_password')), DisplayMultipleCursors(), # Users can insert processors here. DynamicProcessor( lambda: merge_processors(self.input_processors or [])), # For single line mode, show the prompt before the input. ConditionalProcessor( merge_processors([ BeforeInput(get_prompt_text_2), ShowArg(), ]), ~dyncond('multiline')) ] # Create bottom toolbars. bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', dont_extend_height=True, height=Dimension(min=1)), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) search_toolbar = SearchToolbar( search_buffer, ignore_case=dyncond('search_ignore_case')) search_buffer_control = SearchBufferControl( buffer=search_buffer, input_processors=[ ReverseSearchProcessor(), ShowArg(), ], ignore_case=dyncond('search_ignore_case')) system_toolbar = SystemToolbar( enable_global_bindings=dyncond('enable_system_prompt')) def get_search_buffer_control(): " Return the UIControl to be focused when searching start. " if _true(self.multiline): return search_toolbar.control else: return search_buffer_control default_buffer_control = BufferControl( buffer=default_buffer, search_buffer_control=get_search_buffer_control, input_processors=all_input_processors, include_default_input_processors=False, lexer=DynamicLexer(lambda: self.lexer), preview_search=True) default_buffer_window = Window( default_buffer_control, height=self._get_default_buffer_control_height, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation fragments. ConditionalMargin( PromptMargin(get_prompt_text_2, self._get_continuation), filter=dyncond('multiline'), ) ], wrap_lines=dyncond('wrap_lines')) @Condition def multi_column_complete_style(): return self.complete_style == CompleteStyle.MULTI_COLUMN # Build the layout. layout = HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ ConditionalContainer( Window(FormattedTextControl(get_prompt_text_1), dont_extend_height=True), Condition(has_before_fragments)), ConditionalContainer( default_buffer_window, Condition(lambda: get_app().layout.current_control != search_buffer_control), ), ConditionalContainer( Window(search_buffer_control), Condition(lambda: get_app().layout.current_control == search_buffer_control), ), ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=has_focus(default_buffer) & ~multi_column_complete_style)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( show_meta=True, extra_filter=has_focus(default_buffer) & multi_column_complete_style)), # The right prompt. Float(right=0, top=0, hide_when_covering_content=True, content=_RPrompt(lambda: self.rprompt)), ]), ConditionalContainer(ValidationToolbar(), filter=~is_done), ConditionalContainer(system_toolbar, dyncond('enable_system_prompt') & ~is_done), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer( Window(FormattedTextControl(self._get_arg_text), height=1), dyncond('multiline') & has_arg), ConditionalContainer(search_toolbar, dyncond('multiline') & ~is_done), bottom_toolbar, ]) return Layout(layout, default_buffer_window)
def __init__(self, event): def dialog_opener(authtype, auth={}): if authtype == 'basic': BasicAuthDialog(event, auth) elif authtype == 'digest': DigestAuthDialog(event, auth) def ok_handler(): root_container.floats.pop() authtype = self.radio_list.current_value['authtype'] dialog_opener(authtype) def cancel_handler(): root_container.floats.pop() root_container.float_container.key_bindings = None event.app.layout.focus(ButtonManager.prev_button) kb = KeyBindings() server = db.fetch_one(name=ButtonManager.current_button) if server.auth: auth = json.loads(server.auth) auth_type = auth.get('type') dialog_opener(auth_type, auth=auth) else: ok_button = Button(text='OK', handler=ok_handler) cancel_button = Button(text='Cancel', handler=cancel_handler) self.radio_list = RadioList(values=[({ 'authtype': 'basic' }, 'Basic'), ({ 'authtype': 'digest' }, 'Digest')]) kb = self.radio_list.control.key_bindings @kb.add('j') def down(event): self.radio_list._selected_index = min( len(self.radio_list.values) - 1, self.radio_list._selected_index + 1) @kb.add('k') def up(event): self.radio_list._selected_index = max( 0, self.radio_list._selected_index - 1) @kb.add('g', 'g') def top(event): self.radio_list._selected_index = 0 @kb.add('G') def bottom(event): self.radio_list._selected_index = len( self.radio_list.values) - 1 self.dialog = Dialog(title='Select auth type', body=self.radio_list, buttons=[ok_button, cancel_button], width=D(preferred=80), with_background=True, modal=True) root_container.float_container.key_bindings = kb root_container.floats.append(Float(self.dialog)) event.app.layout.focus(self.dialog)
def create_layout(self): # Create functions that will dynamically split the prompt. (If we have # a multiline prompt.) has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \ _split_multiline_prompt(self.formatted_message) default_buffer = ModalBuffer( name=DEFAULT_BUFFER, complete_while_typing=Condition( lambda: self.complete_while_typing), completer=DynamicCompleter(lambda: self.completer), history=self.history, get_tempfile_suffix=lambda: self.tempfile_suffix) search_buffer = Buffer(name=SEARCH_BUFFER) search_toolbar = SearchToolbar(search_buffer) input_processor = merge_processors([ ConditionalProcessor(HighlightSearchProcessor(preview_search=True), has_focus(search_buffer)), HighlightSelectionProcessor(), HighlightMatchingBracketProcessor(), DisplayMultipleCursors() ]) default_buffer_control = BufferControl( buffer=default_buffer, search_buffer_control=search_toolbar.control, input_processor=input_processor, lexer=DynamicLexer(lambda: self.lexer), preview_search=True) def get_default_buffer_control_height(): # 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. space = self.reserve_space_for_menu if space and not get_app().is_done: buff = default_buffer if buff.complete_while_typing( ) or buff.complete_state is not None: return Dimension(min=space) return Dimension() def get_continuation(width): prompt_continuation = self.prompt_continuation if callable(prompt_continuation): prompt_continuation = prompt_continuation(width) return to_formatted_text(prompt_continuation, style='class:prompt-continuation') default_buffer_window = Window( default_buffer_control, height=get_default_buffer_control_height, left_margins=[PromptMargin(get_prompt_text_2, get_continuation)], wrap_lines=True) def get_arg_text(): arg = self.app.key_processor.arg if arg == '-': arg = '-1' return [('class:arg-toolbar', 'Repeat: '), ('class:arg-toolbar.text', arg)] # Build the layout. layout = HSplit([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ ConditionalContainer( Window(FormattedTextControl(get_prompt_text_1), dont_extend_height=True), Condition(has_before_fragments)), default_buffer_window, ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( show_meta=True, extra_filter=has_focus(default_buffer))) ]), ConditionalContainer( Window(FormattedTextControl(get_arg_text), height=1), has_arg), search_toolbar ]) return Layout(layout, default_buffer_window)
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 main(): manager = KeyBindingManager(enable_system_bindings=Always()) D = LayoutDimension layout = HSplit([ VSplit([ Window(width=D(min=15, max=30, preferred=30), content=FillControl('a', token=Token.A)), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=TokenListControl.static([(Token.HelloWorld, lipsum)])), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), Window(content=BufferControl( lexer=PygmentsLexer(PythonLexer), margin=NumberredMargin(), input_processors=[ DefaultPrompt.from_message('python> '), AfterInput.static(' <python', token=Token.AfterInput), ]), ), Window(width=D.exact(1), content=FillControl('|', token=Token.Line)), HSplit([ Window(width=D(max=40), height=D.exact(4), content=FillControl('b', token=Token.B)), Window(width=D(max=40), content=FillControl('f', token=Token.F)), Window(width=D.exact(30), height=D.exact(2), content=FillControl('c', token=Token.C)), ]), #CompletionsMenu(), ]), Window(height=D.exact(1), content=FillControl('-', token=Token.Line)), Window(height=D.exact(3), content=FillControl('d', token=Token.D)), SystemToolbar(), ArgToolbar(), CompletionsToolbar(), SearchToolbar(), ]) layout = FloatContainer(content=layout, floats=[ Float(xcursor=True, ycursor=True, content=VSplit([ Window(width=D.exact(5), content=FillControl( 'f', token=Token.F)), CompletionsMenu(), ])), ]) eventloop = create_eventloop() application = Application(layout=layout, style=TestStyle, key_bindings_registry=manager.registry, buffer=Buffer(is_multiline=Always(), completer=TestCompleter())) cli = CommandLineInterface(application=application, eventloop=eventloop) cli.run() eventloop.close()