def create_cmd_bar(self): ctx = self.ctx def get_cmd_prefix(): has_focus = ctx.app.layout.current_buffer is ctx.cmd_buffer cls = style.COMMAND_FOCUSED if has_focus: text = f"<{cls}>> </{cls}>" else: text = "> " return HTML(text) return Window( BufferControl( ctx.cmd_buffer, focus_on_click=True, input_processors=[BeforeInput(get_cmd_prefix)], key_bindings=cmd_kb, lexer=PygmentsLexer(CommandLexer), ), height=1, )
def main(): cli = CommandLineInterface(layout=Window(BufferControl(input_processors=[ClockPrompt()]))) def on_read_start(): """ This function is called when we start reading at the input. (Actually the start of the read-input event loop.) """ # Following function should be run in the background. # We do it by using an executor thread from the `CommandLineInterface` # instance. def run(): # Send every second a redraw request. while cli.is_reading_input: time.sleep(1) cli.request_redraw() cli.run_in_executor(run) cli.onReadInputStart += on_read_start code_obj = cli.read_input() print('You said: %s' % code_obj.text)
def create_inquirer_layout( ic: InquirerControl, get_prompt_tokens: Callable[[], List[Tuple[str, str]]], **kwargs: Any, ) -> Layout: """Create a layout combining question and inquirer selection.""" ps = PromptSession(get_prompt_tokens, reserve_space_for_menu=0, **kwargs) _fix_unecessary_blank_lines(ps) validation_prompt = PromptSession(bottom_toolbar=lambda: ic.error_message, **kwargs) return Layout( HSplit([ ps.layout.container, ConditionalContainer(Window(ic), filter=~IsDone()), ConditionalContainer( validation_prompt.layout.container, filter=Condition(lambda: ic.error_message is not None), ), ]))
def __init__(self, title: AnyFormattedText = "", style: str = "", width: AnyDimension = None, height: AnyDimension = None, key_bindings: Optional[KeyBindings] = None, modal: bool = False): buffer = Buffer(read_only=True, name='diff') self._search = SearchToolbar(vi_mode=True) self.control = DiffControl(buffer, self._search.control) body = HSplit([ Window(self.control, right_margins=[ScrollbarMargin(display_arrows=True)]), self._search ]) super().__init__(body=body, title=title, style=style, width=width, height=height, key_bindings=key_bindings, modal=modal)
def textbox(buffer, title, lexer=None): def get_style(): ctx = context.get() if ctx.app.layout.current_buffer is buffer: cls = style.TEXTBOX_FOCUSED else: cls = style.TEXTBOX return f"class:{cls}" return HSplit([ FormattedTextToolbar( text=title, style=get_style, ), Window( cursorline=True, content=BufferControl( buffer=buffer, focus_on_click=True, lexer=lexer, ), ignore_content_width=True, ), ])
def __enter__(self) -> 'ProgressBar': # Create UI Application. title_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.title), height=1, style='class:progressbar,title'), filter=Condition(lambda: self.title is not None)) bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: self.bottom_toolbar, style='class:bottom-toolbar.text'), style='class:bottom-toolbar', height=1), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None)) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window(content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f)) for f in self.formatters ] self.app: Application[None] = Application( min_redraw_interval=.05, layout=Layout( HSplit([ title_toolbar, VSplit(progress_controls, height=lambda: D(preferred=len(self.counters), max=len(self.counters))), Window(), bottom_toolbar, ])), style=self.style, key_bindings=self.key_bindings, color_depth=self.color_depth, output=self.output, input=self.input) # Run application in different thread. def run() -> None: set_event_loop(self._app_loop) with _auto_refresh_context(self.app, .3): try: self.app.run() except BaseException as e: traceback.print_exc() print(e) self._thread = threading.Thread(target=run) self._thread.start() # Attach WINCH signal handler in main thread. # (Interrupt that we receive during resize events.) self._has_sigwinch = hasattr(signal, 'SIGWINCH') and in_main_thread() if self._has_sigwinch: self._previous_winch_handler = signal.getsignal(signal.SIGWINCH) self._loop.add_signal_handler(signal.SIGWINCH, self.invalidate) return self
def create_buffer_window_separator(buffer_name): return Window(width=D.exact(1), content=FillControl('\u2502', token=Token.Separator), filter=~IsDone() & show_all_buffers)
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()
def _get_main_title_layout(self): return Frame(Window(FormattedTextControl(HTML("<u>PyTicker</u>")), height=1, align=WindowAlign.CENTER), style=PyTickerStyles.DARK_GREY_BACKGROUND_BLACK_TEXT)
def create_prompt_layout(self, message='', lexer=None, is_password=False, reserve_space_for_menu=8, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False, wrap_lines=True): """Create a Container instance for a prompt. Parameters ---------- message : Text to be used as prompt. lexer : ~prompt_toolkit.layout.lexers.Lexer to be used for the highlighting. is_password : bool or ~prompt_toolkit.filters.CLIFilter. When True, display input as '*'. reserve_space_for_menu : Space to be reserved for the menu. When >0, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. get_prompt_tokens : An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) get_bottom_toolbar_tokens : An optional callable that returns the tokens for a toolbar at the bottom. display_completions_in_columns : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in multiple columns. multiline : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. wrap_lines : `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True (the default), automatically wrap long lines instead of scrolling horizontally. Notes ----- This method was forked from the mainline prompt-toolkit repo. Copyright (c) 2014, Jonathan Slenders, All rights reserved. WARNING; This method is due for removal once prompt-toolkit >v0.54 is released. """ assert isinstance(message, str) assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt( get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if issubclass(lexer, pygments.lexer.Lexer): lexer = PygmentsLexer(lexer) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create highlighters and processors list. if ConditionalHighlighter is None: highlighters = None highlighters_kwargs = {} else: highlighters = [ ConditionalHighlighter( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) SearchHighlighter(preview_search=True), HasFocus(SEARCH_BUFFER)), SelectionHighlighter() ] highlighters_kwargs = {'highlighters': highlighters} input_processors = [ ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password) ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) # (DefaultPrompt should always be at the end of the processors.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer( Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char( ' ', Token.Toolbar)), height=LayoutDimension.exact(1)), filter=~IsDone() & RendererHeightIsKnown()) ] 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=reserve_space_for_menu) else: return LayoutDimension() # Create and return Container instance. return HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), filter=multiline, ), VSplit([ # In multiline mode, the prompt is displayed in a left pane. ConditionalContainer( Window( TokenListControl(get_prompt_tokens_2), dont_extend_width=True, ), filter=multiline, ), # The main input, with completion menus floating on top of it. FloatContainer( Window( BufferControl( input_processors=input_processors, lexer=lexer, wrap_lines=wrap_lines, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=True, **highlighters_kwargs), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=HasFocus(DEFAULT_BUFFER) & display_completions_in_columns, show_meta=True)) ]), ]), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
def __init__(self): # styling style = Style.from_dict({ 'completion-menu.completion': 'bg:#008888 #ffffff', 'completion-menu.completion.current': 'bg:#00aaaa #000000', 'scrollbar.background': 'bg:#88aaaa', 'scrollbar.button': 'bg:#222222', 'input-field': '#004400', 'buffer': '#ff0066', }) # create input fields self.source_field = make_text_area('[Source folder]: ') self.target_field = make_text_area('[Target folder]: ') self.dry_field = make_text_area('[{:13}]: '.format("Dry? (y/n)")) # get completers initialize_database() con = db_connect() self.source_field.completer = FuzzyCompleter( WordCompleter(get_source_paths(con), ignore_case=True)) self.target_field.completer = FuzzyCompleter( WordCompleter(get_target_paths(con), ignore_case=True)) self.dry_field.completer = WordCompleter( ['Yes', 'No', 'True', 'False', 'yes', 'no'], ignore_case=True) # bottom toolbar def bottom_toolbar_call(): s1 = '<b><style bg="ansired">C-H</style></b>: history mode.' s2 = '<b><style bg="ansired">C-C/C-Q</style></b>: exit app.' s3 = '<b><style bg="ansired">C-O</style></b>: ordered paths.' s4 = '<b><style bg="ansired">C-R</style></b>: reverse paths.' return HTML(" ".join([s1, s2, s3, s4])) self.bottom_toolbar = ConditionalContainer( Window(FormattedTextControl(lambda: bottom_toolbar_call, 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: bottom_toolbar_call is not None))) # create app body self.body = FloatContainer(content=HSplit(children=[ self.source_field, self.target_field, self.dry_field, self.bottom_toolbar ], height=8), floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=12, scroll_offset=1)) ]) # define internal logic def execute_command(buff): """Send command to subprocess dealing with dry argument recursively""" dry = False if buff.text.lower() in ['n', 'no', 'false'] else True dry_flag = 'DRY' if dry else 'NOT DRY' dry_string = 'n' if dry else '' command = "rsync -avucP{} {} {}".format(dry_string, self.source_field.text, self.target_field.text) def run_script(): subprocess.call(command, shell=True) def print_info(): print_formatted_text( HTML('<ansired>{} </ansired>'.format(dry_flag))) print_formatted_text( HTML('<ansired>{} </ansired>'.format( 'You entered: {}'.format(command)))) print_formatted_text( HTML('<ansired>{} </ansired>'.format('Running...'))) run_in_terminal(print_info) if dry: run_in_terminal(run_script) return else: con = db_connect() create_rsync_record(con, self.source_field.text, self.target_field.text) run_in_terminal(run_script) app = get_app() app.exit() return self.dry_field.buffer.accept_handler = execute_command # Key bindings self.kb = KeyBindings() @self.kb.add('c-q') @self.kb.add('c-c') def _(event): " Quit application. " event.app.exit() #kb.add('enter')(focus_next) self.kb.add('tab')(focus_next) self.kb.add('s-tab')(focus_previous) # The `Application` self.app = Application( layout=Layout(self.body), #style=style, key_bindings=self.kb, full_screen=False, mouse_support=True)
def _create_app(self): # Create UI Application. title_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.title), height=1, style="class:progressbar,title", ), filter=Condition(lambda: self.title is not None), ) bottom_toolbar = ConditionalContainer( Window( FormattedTextControl( lambda: self.bottom_toolbar, style="class:bottom-toolbar.text" ), style="class:bottom-toolbar", height=1, ), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None), ) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window( content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f), ) for f in self.formatters ] body = self.create_content(progress_controls) self.root = FloatContainer( content=HSplit( [ title_toolbar, body, bottom_toolbar, ] ), floats=[] ) if self.key_bindings is None: self.create_key_bindings() self.app: Application[None] = Application( min_redraw_interval=0.05, layout=Layout(self.root), style=self.style, key_bindings=self.key_bindings, refresh_interval=0.3, color_depth=self.color_depth, output=self.output, input=self.input, full_screen=True, ) return self.app
def __init__(self): super().__init__(None, None, Window(height=1))
def __init__(self, username: str, password: str): super().__init__(username, password, handle_data=DataFormat.ANSI) self.commands = [] self.output_buffer = Buffer_() self.cursor_pos = 0 self.chat_buffer = Buffer_() self.output = BufferControl(self.output_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.chat = BufferControl(self.chat_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.hide_ip = "--hide-ip" in sys.argv self.suggest = AutoSuggestFromLogs([ CommandSuggest(), ]) self.input = TextArea(height=1, prompt=" >> ", multiline=False, wrap_lines=False, accept_handler=self.accept, auto_suggest=self.suggest, dont_extend_width=True) self.host_ip = FormattedTextControl(ANSI("")) self.chat_float = Float(Frame(Window(self.chat, wrap_lines=True)), right=1, top=0, width=40, height=12, hide_when_covering_content=True) self.text = "" self.chat_text = "" def set_frame_size(fn): def inner(*args): size = self.app.output.get_size() self.chat_float.width = size.columns // 3 self.chat_float.height = size.rows // 2 return fn(*args) return inner self.out_window = Window(self.output, wrap_lines=True) kb = KeyBindings() @kb.add('c-c') @kb.add('c-q') def _(_): self.app.exit() self._loop = False self.run_again = False @kb.add('c-i', filter=has_focus(self.input)) def __(_): fut = self.suggest.get_suggestion_future(self.input.buffer, self.input.document) text = self.input.text def set_input(fut_2): res = fut_2.result() if res is not None: self.input.text = text + res.text self.input.document = Document(self.input.text, cursor_position=len( self.input.text)) fut.add_done_callback(set_input) @kb.add(Keys.ScrollUp) def sup(_): self.output_buffer.cursor_up(1) self.out_window._scroll_up() # pylint: disable=protected-access @kb.add(Keys.ScrollDown) def sdown(_): self.output_buffer.cursor_down(1) self.out_window._scroll_down() # pylint: disable=protected-access self.app = Application( layout=Layout( container=HSplit([ Frame( FloatContainer(self.out_window, floats=[self.chat_float])), Frame( VSplit([ self.input, Window(self.host_ip, align=WindowAlign.RIGHT, dont_extend_width=True) ])) ]), focused_element=self.input, ), full_screen=True, mouse_support=True, enable_page_navigation_bindings=True, key_bindings=merge_key_bindings([kb]), paste_mode=True, ) self.app._on_resize = set_frame_size(self.app._on_resize) # pylint: disable=protected-access self.run_again = True self.loop = get_event_loop() self._loop = False self.own_pass = "" self.own_ip = "" self.current_ip = ""
class UI(Client): def __init__(self, username: str, password: str): super().__init__(username, password, handle_data=DataFormat.ANSI) self.commands = [] self.output_buffer = Buffer_() self.cursor_pos = 0 self.chat_buffer = Buffer_() self.output = BufferControl(self.output_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.chat = BufferControl(self.chat_buffer, input_processors=[FormatText()], include_default_input_processors=True) self.hide_ip = "--hide-ip" in sys.argv self.suggest = AutoSuggestFromLogs([ CommandSuggest(), ]) self.input = TextArea(height=1, prompt=" >> ", multiline=False, wrap_lines=False, accept_handler=self.accept, auto_suggest=self.suggest, dont_extend_width=True) self.host_ip = FormattedTextControl(ANSI("")) self.chat_float = Float(Frame(Window(self.chat, wrap_lines=True)), right=1, top=0, width=40, height=12, hide_when_covering_content=True) self.text = "" self.chat_text = "" def set_frame_size(fn): def inner(*args): size = self.app.output.get_size() self.chat_float.width = size.columns // 3 self.chat_float.height = size.rows // 2 return fn(*args) return inner self.out_window = Window(self.output, wrap_lines=True) kb = KeyBindings() @kb.add('c-c') @kb.add('c-q') def _(_): self.app.exit() self._loop = False self.run_again = False @kb.add('c-i', filter=has_focus(self.input)) def __(_): fut = self.suggest.get_suggestion_future(self.input.buffer, self.input.document) text = self.input.text def set_input(fut_2): res = fut_2.result() if res is not None: self.input.text = text + res.text self.input.document = Document(self.input.text, cursor_position=len( self.input.text)) fut.add_done_callback(set_input) @kb.add(Keys.ScrollUp) def sup(_): self.output_buffer.cursor_up(1) self.out_window._scroll_up() # pylint: disable=protected-access @kb.add(Keys.ScrollDown) def sdown(_): self.output_buffer.cursor_down(1) self.out_window._scroll_down() # pylint: disable=protected-access self.app = Application( layout=Layout( container=HSplit([ Frame( FloatContainer(self.out_window, floats=[self.chat_float])), Frame( VSplit([ self.input, Window(self.host_ip, align=WindowAlign.RIGHT, dont_extend_width=True) ])) ]), focused_element=self.input, ), full_screen=True, mouse_support=True, enable_page_navigation_bindings=True, key_bindings=merge_key_bindings([kb]), paste_mode=True, ) self.app._on_resize = set_frame_size(self.app._on_resize) # pylint: disable=protected-access self.run_again = True self.loop = get_event_loop() self._loop = False self.own_pass = "" self.own_ip = "" self.current_ip = "" # patch_stdout() @classmethod def create(cls) -> 'UI': user = prompt("Username: "******"Password: "******"{Fore.BLUE}[BROADCAST]{Fore.RESET} {converted_color_codes(e.msg)}" ) else: self.set_output(converted_color_codes(e.msg)) def event_error(self, e: ErrorEvent): self.err(e.error) @staticmethod def sanitize(arg: str) -> ANSI: return to_formatted_text(ANSI(arg)) def err(self, message: str): self.set_output( f"{Fore.RED}{converted_color_codes(message)}{Fore.RESET}") def set_chat_output(self, text: str): new_text = (self.chat_text + "\n" + text).strip() self.chat_buffer.set_text(new_text) self.chat_text = new_text.replace("\t", " ") def set_output(self, text: str): new_text = (self.text + "\n" + text).strip() self.output_buffer.set_text(new_text) self.text = new_text.replace("\t", " ") self.cursor_pos = len(self.text) def clear_chat(self): self.chat_buffer.set_text("") self.chat_text = "" def clear(self): self.output_buffer.set_text("") self.text = "" def accept(self, _): if self.input.text.strip(): self.set_output(f"\n>> {self.input.text}") self.commands.append(self.input.text) self.suggest.last_command(self.input.text) self.input.text = "" async def get_host_data(self): data = await self.command("pass see -l") self.own_pass = data.msg sys_info = await self.command('specs -l') self.current_ip = self.own_ip = re.search( r"(?P<ip>\d{1,3}(\.\d{1,3}){3,4})", sys_info.msg).group("ip") def launch(self): colorama.init() use_asyncio_event_loop() patch_stdout() while self.run_again: self.run_again = False self._loop = True self.loop.create_task(self.start()) try: self.loop.run_until_complete( self.app.run_async().to_asyncio_future()) except KeyboardInterrupt: if self.current_ip != self.own_ip: self.loop.run_until_complete(self.command("dc")) async def event_ready(self): o_text = self.output_buffer.text await self.get_host_data() text = (( f"{Fore.YELLOW}{self.own_ip} - {self.own_pass}{Fore.RESET} " if self.own_ip == self.current_ip else f"{Fore.YELLOW}{self.current_ip} / {self.own_ip} - {self.own_pass}{Fore.RESET} " ) if not self.hide_ip else "") self.host_ip.text = self.sanitize(text) self.clear() self.set_output(o_text) macros = MacroHolder() while self._loop: # TODO: Update these when they change macros.macros["self"] = self.own_ip macros.macros["pass"] = self.own_pass while not self.commands: await asyncio.sleep(0.1) try: line = self.commands.pop(0).strip() line = macros.parse(line) command, *args = line.split() if command == "chats": if len(args) == 1 and args[0] == "clear": self.clear_chat() else: await self.command(" ".join([command, *args])) elif command == "macro": if args and args[0] in ("add", "remove", "list"): sub = args.pop(0) if sub == "add": if len(args) >= 2: macros += args[0], " ".join(args[1:]) else: self.set_output( "Usage: macro add <name> <value>") elif sub == "remove": if args: macros -= args[0] else: self.set_output("Usage: macro remove <name>") else: self.set_output("Macros:") for key in sorted(list(macros)): self.set_output(f"${key} -> {macros[key]}") else: self.set_output("Usage: macro [add/remove/list] ...") elif command == "clear": self.clear() elif command == "quit": self._loop = False self.run_again = False self.stop() self.app.exit() else: await self.command(" ".join([command, *args])) except Exception as e: # pylint: disable=broad-except self.err(repr(e))
Label(text=', '.join( [f'{k}:{v}' for k, v in c.__dict__.items() if k != 'tag'])) for c in jvm.class_files[class_name].const_pool ], ] frames = [list(f) for f in zip(*frames)] CONST_POOL_PAGES = [] for i in range(0, len(frames), 14): frames_chunk = frames[i:i + 14] page = Layout( HSplit([ VSplit([HSplit([Frame(VSplit(frame)) for frame in frames_chunk])]), Window(), Label('LEFT/RIGHT: change page. v: toggle view. q: quit.') ])) CONST_POOL_PAGES += [page] # start the JVM and record the Layout at each step log.info(f'Recording the execution of {method}...') ERROR = False try: stdout = jvm.call_function(method, arguments) except Exception as e: log.exception('Something went wrong during the execution') ERROR = True if not LAYOUT_STACK:
def _create_layout(self, message='', lexer=None, is_password=False, reserve_space_for_menu=8, get_prompt_tokens=None, get_continuation_tokens=None, get_rprompt_tokens=None, get_bottom_toolbar_tokens=None, get_url_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False, wrap_lines=True): """ Create a :class:`.Container` instance for a prompt. :param message: Text to be used as prompt. :param lexer: :class:`~prompt_toolkit.layout.lexers.Lexer` to be used for the highlighting. :param is_password: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, display input as '*'. :param reserve_space_for_menu: Space to be reserved for the menu. When >0, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_continuation_tokens: An optional callable that takes a CommandLineInterface and width as input and returns a list of (Token, text) tuples to be used for the continuation. :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. :param display_completions_in_columns: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. Display the completions in multiple columns. :param multiline: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. :param wrap_lines: `bool` or :class:`~prompt_toolkit.filters.CLIFilter`. When True (the default), automatically wrap long lines instead of scrolling horizontally. """ assert get_bottom_toolbar_tokens is None or callable( get_bottom_toolbar_tokens) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert get_rprompt_tokens is None or callable(get_rprompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] has_before_tokens, get_prompt_tokens_1, get_prompt_tokens_2 = \ _split_multiline_prompt(get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if pygments_Lexer and issubclass(lexer, pygments_Lexer): lexer = PygmentsLexer(lexer, sync_from_start=True) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create processors list. input_processors = [ ConditionalProcessor( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) HighlightSearchProcessor(preview_search=True), HasFocus(SEARCH_BUFFER)), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password), DisplayMultipleCursors(DEFAULT_BUFFER), ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) # (DefaultPrompt should always be at the end of the processors.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens_2), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer(VSplit([ Window(TokenListControl(get_url_tokens, default_char=Char( ' ', Token.Toolbar)), height=LayoutDimension.exact(1)), Window(TokenListControl(get_bottom_toolbar_tokens, default_char=Char( ' ', Token.Toolbar), align_right=True), height=LayoutDimension.exact(1)) ]), filter=~IsDone() & RendererHeightIsKnown()) ] 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: 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([ # The main input, with completion menus floating on top of it. FloatContainer( HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), Condition(has_before_tokens)), Window( BufferControl( input_processors=input_processors, lexer=lexer, # Enable preview_search, we want to have immediate feedback # in reverse-i-search mode. preview_search=True), get_height=get_height, left_margins=[ # In multiline mode, use the window margin to display # the prompt and continuation tokens. ConditionalMargin(PromptMargin( get_prompt_tokens_2, get_continuation_tokens), filter=multiline) ], wrap_lines=wrap_lines, ), ]), [ # Completion menus. Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns)), Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=HasFocus(DEFAULT_BUFFER) & display_completions_in_columns, show_meta=True)), # The right prompt. Float(right=0, top=0, hide_when_covering_content=True, content=_RPrompt(get_rprompt_tokens)), ]), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
def _run(self): class MenuColorizer(Processor): def apply_transformation(_self, ti): return self._transform_line(ti) # keybindings self._kb = KeyBindings() @self._kb.add('q', filter=~is_searching) @self._kb.add('c-c') def quit(event): event.app.exit() @self._kb.add('down', filter=~is_searching) @self._kb.add('j', filter=~is_searching) def down(event): self.next_item(1) @self._kb.add('up', filter=~is_searching) @self._kb.add('k', filter=~is_searching) def up(event): self.next_item(-1) @self._kb.add('N', filter=~is_searching) @self._kb.add('n', filter=~is_searching) def search_inc(event, filter=is_searching): if not self._bufctrl.search_state.text: return search_dir = 1 if event.data == 'n' else -1 sr_lines = self._get_search_result_lines() if sr_lines: line = sr_lines[search_dir] if len( sr_lines) > 1 else sr_lines[0] self.sync_cursor_to_line(line, search_dir) @self._kb.add('c-m', filter=~is_searching) @self._kb.add('right', filter=~is_searching) def accept(event): self._success = True event.app.exit() @self._kb.add('c-m', filter=is_searching) def accept_search(event): search.accept_search() new_line, _ = self._doc.translate_index_to_position( self._buf.cursor_position) self.sync_cursor_to_line(new_line) self._register_extra_kb_cbs(self._kb) self._searchbar = SearchToolbar(ignore_case=True) text = '\n'.join(map(lambda _x: _x.text, self._items)) self._doc = Document(text, cursor_position=self._pos) self._buf = Buffer(read_only=True, document=self._doc) self._bufctrl = BufferControl( self._buf, search_buffer_control=self._searchbar.control, preview_search=True, input_processors=[MenuColorizer()]) split = HSplit([ Window(self._bufctrl, wrap_lines=True, always_hide_cursor=True), self._searchbar ]) # set initial pos self.sync_cursor_to_line(0) app = Application(layout=Layout(split), key_bindings=self._kb, full_screen=False, mouse_support=False) app.run() self._ran = True
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 get_watchlist_stocks_view(self): return Window(content=WATCHLIST_STOCKS_TEXT, ignore_content_width=True, align=WindowAlign.LEFT)
def exit_clicked(_=None): get_app().exit() # All the widgets for the UI. btn_start = Button("Start", handler=tomato.start) btn_pause = Button("Pause", handler=tomato.pause) btn_reset = Button("Reset", handler=tomato.reset) btn_reset_all = Button("Reset All", handler=tomato.reset_all) btn_exit = Button("Exit", handler=exit_clicked) text_area = FormattedTextControl(focusable=False, show_cursor=False) text_window = Window( content=text_area, dont_extend_height=True, height=11, style="bg:#ffffff #000000" ) root_container = Box( HSplit( [ Label(text="Press `Tab` to move the focus."), HSplit( [ VSplit( [btn_start, btn_pause, btn_reset, btn_reset_all, btn_exit], padding=1, style="bg:#cccccc", ), text_window, ]
def get_positions_stocks_view(self): return Window(content=POSITION_STOCKS_TEXT, ignore_content_width=True, align=WindowAlign.LEFT)
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 separator(): return ConditionalContainer(content=Window( height=LayoutDimension.exact(1), content=FillControl(u'\u2500', token=Token.Separator)), filter=HasDocumentation(app) & ~IsDone())
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_default_layout(app, message='', lexer=None, is_password=False, reserve_space_for_menu=False, get_prompt_tokens=None, get_bottom_toolbar_tokens=None, display_completions_in_columns=False, extra_input_processors=None, multiline=False): """ Generate default layout. Returns a ``Layout`` instance. :param message: Text to be used as prompt. :param lexer: Lexer to be used for the highlighting. :param is_password: `bool` or `CLIFilter`. When True, display input as '*'. :param reserve_space_for_menu: When True, make sure that a minimal height is allocated in the terminal, in order to display the completion menu. :param get_prompt_tokens: An optional callable that returns the tokens to be shown in the menu. (To be used instead of a `message`.) :param get_bottom_toolbar_tokens: An optional callable that returns the tokens for a toolbar at the bottom. :param display_completions_in_columns: `bool` or `CLIFilter`. Display the completions in multiple columns. :param multiline: `bool` or `CLIFilter`. When True, prefer a layout that is more adapted for multiline input. Text after newlines is automatically indented, and search/arg input is shown below the input, instead of replacing the prompt. """ assert isinstance(message, text_type) assert (get_bottom_toolbar_tokens is None or callable(get_bottom_toolbar_tokens)) assert get_prompt_tokens is None or callable(get_prompt_tokens) assert not (message and get_prompt_tokens) display_completions_in_columns = to_cli_filter( display_completions_in_columns) multiline = to_cli_filter(multiline) if get_prompt_tokens is None: get_prompt_tokens = lambda _: [(Token.Prompt, message)] get_prompt_tokens_1, get_prompt_tokens_2 = _split_multiline_prompt( get_prompt_tokens) # `lexer` is supposed to be a `Lexer` instance. But if a Pygments lexer # class is given, turn it into a PygmentsLexer. (Important for # backwards-compatibility.) try: if issubclass(lexer, Lexer): lexer = PygmentsLexer(lexer) except TypeError: # Happens when lexer is `None` or an instance of something else. pass # Create processors list. # (DefaultPrompt should always be at the end.) input_processors = [ ConditionalProcessor( # By default, only highlight search when the search # input has the focus. (Note that this doesn't mean # there is no search: the Vi 'n' binding for instance # still allows to jump to the next match in # navigation mode.) HighlightSearchProcessor(preview_search=Always()), HasFocus(SEARCH_BUFFER)), HighlightSelectionProcessor(), ConditionalProcessor(AppendAutoSuggestion(), HasFocus(DEFAULT_BUFFER) & ~IsDone()), ConditionalProcessor(PasswordProcessor(), is_password) ] if extra_input_processors: input_processors.extend(extra_input_processors) # Show the prompt before the input (using the DefaultPrompt processor. # This also replaces it with reverse-i-search and 'arg' when required. # (Only for single line mode.) input_processors.append( ConditionalProcessor(DefaultPrompt(get_prompt_tokens), ~multiline)) # Create bottom toolbar. if get_bottom_toolbar_tokens: toolbars = [ ConditionalContainer(Window(TokenListControl( get_bottom_toolbar_tokens, default_char=Char(' ', Token.Toolbar)), height=LayoutDimension.exact(1)), filter=~IsDone() & RendererHeightIsKnown()) ] 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() def separator(): return ConditionalContainer(content=Window( height=LayoutDimension.exact(1), content=FillControl(u'\u2500', token=Token.Separator)), filter=HasDocumentation(app) & ~IsDone()) # Create and return Layout instance. return HSplit([ ConditionalContainer( Window(TokenListControl(get_prompt_tokens_1), dont_extend_height=True), filter=multiline, ), VSplit([ # In multiline mode, the prompt is displayed in a left pane. ConditionalContainer( Window( TokenListControl(get_prompt_tokens_2), dont_extend_width=True, ), filter=multiline, ), # The main input, with completion menus floating on top of it. 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(), focus_on_click=True, ), get_height=get_height, ), [ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1, extra_filter=(HasFocus(DEFAULT_BUFFER) & ~display_completions_in_columns ))), # noqa E501 Float(xcursor=True, ycursor=True, content=MultiColumnCompletionsMenu( extra_filter=(HasFocus(DEFAULT_BUFFER) & display_completions_in_columns), show_meta=Always())) ]), ]), separator(), ConditionalContainer( content=Window(BufferControl( focus_on_click=True, buffer_name=u'clidocs', ), height=LayoutDimension(max=15)), filter=HasDocumentation(app) & ~IsDone(), ), separator(), ValidationToolbar(), SystemToolbar(), # In multiline mode, we use two toolbars for 'arg' and 'search'. ConditionalContainer(ArgToolbar(), multiline), ConditionalContainer(SearchToolbar(), multiline), ] + toolbars)
def __enter__(self) -> "ProgressBar": # Create UI Application. title_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.title), height=1, style="class:progressbar,title", ), filter=Condition(lambda: self.title is not None), ) bottom_toolbar = ConditionalContainer( Window( FormattedTextControl(lambda: self.bottom_toolbar, style="class:bottom-toolbar.text"), style="class:bottom-toolbar", height=1, ), filter=~is_done & renderer_height_is_known & Condition(lambda: self.bottom_toolbar is not None), ) def width_for_formatter(formatter: Formatter) -> AnyDimension: # Needs to be passed as callable (partial) to the 'width' # parameter, because we want to call it on every resize. return formatter.get_width(progress_bar=self) progress_controls = [ Window( content=_ProgressControl(self, f), width=functools.partial(width_for_formatter, f), ) for f in self.formatters ] self.app: Application[None] = Application( min_redraw_interval=0.05, layout=Layout( HSplit([ title_toolbar, VSplit( progress_controls, height=lambda: D(preferred=len(self.counters), max=len(self.counters)), ), Window(), bottom_toolbar, ])), style=self.style, key_bindings=self.key_bindings, refresh_interval=0.3, color_depth=self.color_depth, output=self.output, input=self.input, ) # Run application in different thread. def run() -> None: set_event_loop(self._app_loop) try: self.app.run(pre_run=self._app_started.set) except BaseException as e: traceback.print_exc() print(e) ctx: contextvars.Context = contextvars.copy_context() self._thread = threading.Thread(target=ctx.run, args=(run, )) self._thread.start() return self
def homeLayoutFactory(self): content = self.studio.content statusBar = Frame( Window(BufferControl(buffer=content.getBuffer("statusBar"), focusable=False), height=D(min=1, max=1, preferred=1), align=WindowAlign.CENTER)) savedModelsBox = Box(HSplit([ Label(text="Saved Models: ", style="class:blue class:underlined"), Window( BufferControl(buffer=content.getBuffer("savedModels"), focusable=False)) ]), padding=0) modelDefinitionsBox = Box(HSplit([ Label(text="Model Definitions: ", style="class:blue class:underlined"), Window( BufferControl(buffer=content.getBuffer("modelDefinitions"), focusable=False)) ]), padding=0) rightSidebar = Frame( HSplit([savedModelsBox, HorizontalLine(), modelDefinitionsBox])) createModelButton = Button("[C] Create Model ", handler=self.studio.layouts.swapper( Layouts.CREATE)) loadModelButton = Button("[L] Load Saved Model ", handler=self.studio.layouts.swapper( Layouts.LOAD)) importModelButton = Button("[I] Import Model From Definition ", handler=self.studio.layouts.swapper( Layouts.IMPORT)) editModelButton = Button("[E] Edit Model ", handler=self.studio.layouts.swapper( Layouts.EDIT)) deleteModelButton = Button("[D] Delete Model ", handler=self.studio.layouts.swapper( Layouts.DELETE)) quitButton = Button("[Q] Quit ", handler=self.studio.exit) editModelButton = ConditionalContainer( editModelButton, filter=self.studio.controller.modelExistsFilter()) leftSidebar = HSplit([ createModelButton, loadModelButton, importModelButton, editModelButton, deleteModelButton, quitButton, ]) creditBar = Label( text="Created by Samuel Ellertson - github.com/SamuelEllertson", style="class:blue") body = VSplit([Frame(Sizeable(leftSidebar)), Sizeable(rightSidebar)]) root = HSplit([statusBar, body, creditBar]) return Layout(container=root, focused_element=createModelButton)
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)
async def _init(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None: started_values = await aislice(values, PAGE_SIZE) # started_values = await aislice(values, PAGE_SIZE) if not started_values: raise IndexError('Values is empty.') self.values = started_values # current_values will be used in multiple_selection, # current_value will be used otherwise. self.current_values: List[_T] = [] self.current_value: _T = started_values[0][0] self._selected_index = 0 # Key bindings. kb = KeyBindings() @kb.add("up") def _up(event: E) -> None: self._selected_index = max(0, self._selected_index - 1) @kb.add("down") def _down(event: E) -> None: async def handler(event): if self._selected_index + 1 >= len(self.values): self.values.extend(await aislice(values, PAGE_SIZE)) self._selected_index = min( len(self.values) - 1, self._selected_index + 1) asyncio.get_event_loop().create_task(async_handler(handler, event)) @kb.add("pageup") def _pageup(event: E) -> None: w = event.app.layout.current_window if w.render_info: self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines)) @kb.add("pagedown") def _pagedown(event: E) -> None: async def handler(event): w = event.app.layout.current_window if self._selected_index + len( w.render_info.displayed_lines) >= len(self.values): self.values.extend(await aislice(values, PAGE_SIZE)) if w.render_info: self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines), ) asyncio.get_event_loop().create_task(async_handler(handler, event)) @kb.add("enter") def _enter(event: E) -> None: if self.many: event.app.exit(result=self.current_values) else: event.app.exit(result=self.current_value) @kb.add(" ") def _enter(event: E) -> None: self._handle_enter() # Control and window. self.control = FormattedTextControl(self._get_text_fragments, key_bindings=kb, focusable=True) self.window = Window( content=self.control, style=self.container_style, right_margins=[ ConditionalMargin( margin=ScrollbarMargin(display_arrows=True), filter=Condition(lambda: self.show_scrollbar), ), ], dont_extend_height=True, )