def main(): # Create a big layout of many text areas, then wrap them in a `ScrollablePane`. root_container = Frame( ScrollablePane( HSplit([ Frame(TextArea(text=f"label-{i}"), width=Dimension()) for i in range(20) ])) # ScrollablePane(HSplit([TextArea(text=f"label-{i}") for i in range(20)])) ) 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) application.run()
def get_key_bindings(self): key_bindings = KeyBindings() async def print_flange_info(event): async with in_terminal(): self.root_node.flange.info() key_bindings.add("c-f")(print_flange_info) async def print_context(event): async with in_terminal(): pprint.pprint(api.format_dict(self.root_node.context)) key_bindings.add("c-p")(print_context) # async def run_ipython(event): # async with in_terminal(): # from IPython import embed # embed() # # if DevShell.__filter_ipython_installed(): # key_bindings.add("c-i")(run_ipython) return key_bindings
def pt_init(self): def get_prompt_tokens(): return [(Token.Prompt, self.prompt)] if self._ptcomp is None: compl = IPCompleter(shell=self.shell, namespace={}, global_namespace={}, parent=self.shell, ) self._ptcomp = IPythonPTCompleter(compl) kb = KeyBindings() supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP')) kb.add('c-z', filter=supports_suspend)(suspend_to_bg) if self.shell.display_completions == 'readlinelike': kb.add('tab', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & vi_insert_mode | emacs_insert_mode & ~cursor_in_leading_ws ))(display_completions_like_readline) self.pt_app = PromptSession( message=(lambda: PygmentsTokens(get_prompt_tokens())), editing_mode=getattr(EditingMode, self.shell.editing_mode.upper()), key_bindings=kb, history=self.shell.debugger_history, completer=self._ptcomp, enable_history_search=True, mouse_support=self.shell.mouse_support, complete_style=self.shell.pt_complete_style, style=self.shell.style, inputhook=self.shell.inputhook, )
def kbindings(): kb = KeyBindings() # without eager=True delay is too long kb.add(Keys.Escape, eager=True)(lambda event: event.app.layout.focus_last()) @kb.add(Keys.ControlDown) def _(event): focus_next(event) @kb.add(Keys.ControlUp) def _(event): focus_previous(event) @kb.add(Keys.F1) def _(event): """Launch Help Pop Up.""" if not event.app.layout.has_focus(POPUP_BUFFER): popup_buffer = event.app.layout.get_buffer_by_name(POPUP_BUFFER) popup_buffer.update(HELP_TEXT) event.app.layout.focus(POPUP_BUFFER) else: event.app.layout.focus(PROMPT_BUFFER) @kb.add(Keys.ControlQ) def _(event): event.app.exit() emitter.emit("KILLALL") return kb
def _create_global_keybindings() -> KeyBindings: bindings = KeyBindings() bindings.add("c-c")( lambda event: event.app.exit(exception=KeyboardInterrupt)) return bindings
def keys(client, given: Dict[str, Callable[[Event], Any]] = None, *, bind_defaults: bool = True) -> KeyBindings: kb = KeyBindings() if bind_defaults: # @kb.add("c-c") # def interrupt(event): # """Ctrl-Q: Exit program.""" # event.app.exit(exception=KeyboardInterrupt) @kb.add("c-d") def eof(event): """Ctrl-D: Exit program, but only if waiting for input.""" if not client.busy(): event.app.exit(exception=EOFError) @kb.add("c-q") def close(event): """Ctrl-Q: Exit program.""" event.app.exit() if given: for k, v in given.items(): kb.add(k)(v) return kb
async def main(self): bindings = KeyBindings() bindings.add("c-x")(self.stop) bindings.add("c-c")(self.stop) formatters = SCREEN_FORMATTERS.copy() formatters[formatters.index("ShowBar")] = ShowBar(self.losses, sym_a="_", sym_b="🚃 ", sym_c="․") project = os.path.basename(os.getcwd()) print_formatted_text(SCREEN_BANNER.format(__version__, project), style=SCREEN_STYLE, flush=True) self.progress_bar = ProgressBar( bottom_toolbar=SCREEN_TOOLBAR, style=SCREEN_STYLE, key_bindings=bindings, formatters=formatters, ) self.trainer = BasicTrainer(device=self.device) scripts = [f for f in self.registry.functions if "main_" in f.name] # Old-style hard-coded training procedure. if len(scripts) == 0: await self._run_stage(stage="N/A", groups=self.registry.groups()) # New-style user-defined training scripts. if len(scripts) == 1: await scripts[0].function(self)
def _bind() -> KeyBindingsBase: bindings = KeyBindings() self = globals() for key, value in self.items(): if key.startswith('_bind_'): keys = key[6:].split('_') # remove '_bind_' bindings.add(*(Keys[key] for key in keys))(value) return bindings
class PysheetApplication: def __init__(self, formula_text_dialog): self.sheet = Sheet() self.view = SheetView(self.sheet) self.input_mode = False self.config = {} #Load from file self.key_bindings = None self.key_bindings = self.bindings() self.formula_text_dialog = formula_text_dialog def __getitem__(self, item): return self.config.get(item, None) def bindings(self): if self.key_bindings is None: self.key_bindings = KeyBindings() self.key_bindings.add("h", filter=not self.input_mode)( self.move_left_cell) self.key_bindings.add("k", filter=not self.input_mode)( self.move_right_cell) self.key_bindings.add("j", filter=not self.input_mode)( self.move_down_cell) self.key_bindings.add("u", filter=not self.input_mode)( self.move_up_cell) self.key_bindings.add("i", filter=not self.input_mode)( self.enter_input_mode) return self.key_bindings def move_right_cell(self, event): self.view.move_column_right() get_app().invalidate() def move_left_cell(self, event): self.view.move_column_left() get_app().invalidate() def move_up_cell(self, event): self.view.move_row_up() get_app().invalidate() def move_down_cell(self, event): self.view.move_row_down() get_app().invalidate() def enter_input_mode(self, event): self.input_mode = True self.formula_text_dialog.body.text = self.view.get_current_cell_formula( ) self.formula_text_dialog.title = self.view.current_cell_coord() get_app().invalidate() def get_cell_html(self, cell): fmt = "{:>10}" if cell == self.view.current_cell_coord(): fmt = '<style bg="#555555">{:>10}</style>' return fmt.format(self.sheet[cell].value())
def create_key_bindings(self): kb = KeyBindings() @kb.add('c-q') def _(event): self.exit() kb.add("tab")(focus_next) self.key_bindings = kb
def _create_global_keybindings() -> KeyBindings: bindings = KeyBindings() bindings.add("c-c")( lambda event: event.app.exit(exception=KeyboardInterrupt)) bindings.add("tab")(focus_next) bindings.add("right")(focus_next) bindings.add("s-tab")(focus_previous) bindings.add("left")(focus_previous) return bindings
def _create_global_keybindings() -> KeyBindings: """Create keybindings for the whole application.""" bindings = KeyBindings() bindings.add("tab")(focus_next) bindings.add("s-tab")(focus_previous) @bindings.add("c-c") @bindings.add("q") def _exit(event): event.app.exit() return bindings
def start(self): self._running = True self._queue = asyncio.Queue(1) self._loop = asyncio.get_event_loop() self._loop.create_task(self._execute()) kb = KeyBindings() kb.add(Keys.Escape)(self._handle) kb.add(Keys.ControlC)(self._exit) self._prompt_app = Application(layout=Layout(Window()), key_bindings=kb) self._thread = Thread(target=self._prompt_app.run) self._thread.start()
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 prompt(text: Union[str, FormattedText], title: str = '', actions: List[Action] = [], **kwargs: Any) -> None: """A simple and extensible prompt helper routine :param text: Text to be printed before the prompt, it can be formatted text :type text: str or FormattedText :param title: Title to be shown in a bottom bar :type title: str :param actions: A list of Actions as defined in `Action`. :type actions: [Action] :param kwargs: kwargs to prompt_toolkit application class """ assert (isinstance(actions, list)) assert (type(title) == str) kb = KeyBindings() for action in actions: kb.add(action.key)(action.action) print_formatted_text(FormattedText(text)) root_container = HSplit([ Window(wrap_lines=True, height=1, align=WindowAlign.LEFT, always_hide_cursor=True, style='bg:ansiblack fg:ansiwhite', content=FormattedTextControl( focusable=False, text=HTML(' '.join( "{a.name}<yellow>[{a.key}]</yellow>".format(a=a) for a in actions)))) ] + ([ Window(height=1, align=WindowAlign.LEFT, always_hide_cursor=True, style='bold fg:ansipurple bg:ansiwhite', content=FormattedTextControl(focusable=False, text=title)) ] if title else [])) app = Application(layout=Layout(root_container), key_bindings=kb, **kwargs) app.run()
def __init__(self, server: 'ScriptingServer'): # Customize the default builtins, and use DynamicDict # in order to avoid reflection at startup time. builtins = DynamicDict(globals()["__builtins__"]) builtins["print"] = self._custom_print del builtins["help"] del builtins["input"] del builtins["breakpoint"] # Add customized builtins, types and minecraft dynamic # value and also all builtins class wrappers. from . import std, mc builtins["types"] = server.types builtins.add_dyn("mc", lambda: mc.Minecraft.get_instance(server)) for mod_name, cls_name, cls in self.iter_modules_classes(std, mc): builtins[cls_name] = cls self.locals = {} self.globals = {"__builtins__": builtins} self.code_indent = 0 self.code = [] self.lexer = PygmentsLexer(PythonLexer) self.window = RollingLinesWindow(100, lexer=self.lexer, wrap_lines=True, dont_extend_height=True) self.input = TextArea(height=1, multiline=False, wrap_lines=False, accept_handler=self._input_accept, lexer=self.lexer) self.prompt_processor = BeforeInput(">>> ", "") self.input.control.input_processors.clear() self.input.control.input_processors.append(self.prompt_processor) keys = KeyBindings() keys.add("tab", filter=Condition(self.require_key_tab))(self._handle_tab) self.split = HSplit([Window(), self.window, self.input], key_bindings=keys)
def create_app(listen_handler, home): # components logo = Label(text=LOGO) text_area = TextArea(text=str(home), read_only=True, scrollbar=True) listen_btn = Button('Listen', handler=listen_handler(text_area=text_area)) help_btn = Button('Help', handler=help_handler) exit_btn = Button('Exit', handler=lambda: get_app().exit()) buttons = HSplit(children=[ Label(text=' MENU'), Frame(listen_btn), Frame(help_btn), Frame(exit_btn) ], style='bg:#00aa00 #000000') # root container root_container = FloatContainer(HSplit([ Box(body=VSplit([buttons, logo], padding=12), padding=0, style='bg:#888800 #000000'), text_area, ]), floats=[]) # key bindings bindings = KeyBindings() bindings.add('tab')(focus_next) bindings.add('s-tab')(focus_previous) @bindings.add('c-c') @bindings.add('q') def _(event): event.app.exit() # application application = Application(layout=Layout(root_container, focused_element=listen_btn), key_bindings=bindings, enable_page_navigation_bindings=True, mouse_support=True, full_screen=True) return application
def build_application(self, old, container: Container, keys: KeyBindings) -> Application: interpreter = None if self.active: title_text = self.pmc.get_message("start.scripting.title", self.server.get_port()) interpreter = Interpreter(self.server) container = VSplit([ container, Window(char=' ', width=1, style="class:header"), HSplit([ VSplit([ Window(width=2), Window(FormattedTextControl(text=title_text)), ], height=1, style="class:header"), VSplit([Window(width=1), interpreter, Window(width=1)]) ]) ]) keys.add( "tab", filter=~Condition(interpreter.require_key_tab))(focus_next) keys.add( "s-tab", filter=~Condition(interpreter.require_key_tab))(focus_previous) app = old(container, keys) if self.active: app.layout.focus(interpreter.input) return app
def get_key_bindings(): bindings = KeyBindings() bindings.add(Keys.Tab)(focus_next) bindings.add(Keys.Enter)(focus_next) bindings.add(Keys.BackTab)(focus_previous) # CTRL-C to quit the prompt-app. @bindings.add("c-c") def exit_c(event): """Ctrl-C to quit.""" event.app.exit(result=False) return bindings
class Quiz: FG = '#ff0000' BG = '#00ff00' def __init__(self, text_provider: OptionsTextProvider): self.text_provider = text_provider self.keybindings = KeyBindings() self.style = Style([ ('quiz_item_selected', f'bg:{self.BG} fg:{self.FG}'), ('quiz_item_not_selected', f'bg:{self.FG} fg:{self.BG}'), ('empty', '') ]) self.keybindings.add(Keys.Up, eager=True)(lambda _: self.text_provider.up()) self.keybindings.add(Keys.Down, eager=True)(lambda _: self.text_provider.down()) self.keybindings.add(Keys.Enter, eager=True)(self.enter) self.keybindings.add(Keys.Any, eager=True)(lambda _: None) def enter(self, e): self.text_provider.answered = True e.app.exit(result=self.text_provider.current_item)
from pygments.token import Token from pygments.lexers.basic import CbmBasicV2Lexer from prompt_toolkit import Application from prompt_toolkit.layout.containers import Window from prompt_toolkit.layout.controls import FormattedTextControl from prompt_toolkit.layout import Layout, HSplit, VSplit from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous from prompt_toolkit.application.current import get_app from prompt_toolkit.widgets import * from prompt_toolkit.lexers import PygmentsLexer # napojenà na klávesové zkratky key_bindings = KeyBindings() key_bindings.add('s-tab')(focus_previous) key_bindings.add('tab')(focus_next) @key_bindings.add('escape') def on_exit_selected(event=None): """Callback funkce volaná při stisku klávesy Esc.""" get_app().exit() @key_bindings.add('f10') def on_f10_pressed(event=None): """Callback funkce volaná při stisku klávesy F10.""" get_app().layout.focus(menu.window)
Window(width=1, char='|', style='class:line'), #Window(content) HSplit( list([ Window(ctrls.content), Window(height=1, char='=', style='class:line'), ctrls.sender ])) ]) # 2. Key bindings kb = KeyBindings() # Key bindings. kb = KeyBindings() kb.add('tab')(focus_next) kb.add('s-tab')(focus_previous) @kb.add('c-q') def _(event): " Quit application. " event.app.exit() @kb.add('c-a') def _(event): " focus text. " event.app.layout.focus(ctrls.sender)
from prompt_toolkit.key_binding import KeyBindings from textomatic import context kb = KeyBindings() cmd_kb = KeyBindings() kb.add("c-c")(lambda e: e.app.exit()) kb.add("tab")(lambda e: e.app.layout.focus_next()) kb.add("s-tab")(lambda e: e.app.layout.focus_previous()) @kb.add("c-t") def change_boxes_orientation(_): ctx = context.get() ctx.box_veritcal_orientation = not ctx.box_veritcal_orientation @kb.add("c-o") def exit_and_print_output(_): ctx = context.get() ctx.print_output_on_exit = True ctx.app.exit() @kb.add("c-p") def copy_output_to_clipboard(_): ctx = context.get() ctx.app.clipboard.set_text(ctx.output_buffer.text) ctx.copied_to_clipboard = True
class ShopUI(): def __init__(self, player, nameOfShop, shopInventory, shopKeeperAsciiArt=None, customCurrency=None): '''shopInventory is a list of items''' self.player = player self.name = nameOfShop self.shopInventory = shopInventory self.shopKeeperAsciiArt = shopKeeperAsciiArt if self.shopKeeperAsciiArt == None: self.shopKeeperAsciiArt =''' _\|/^ (_oo what can i get for ya | /|\\ | LL ''' self.playerClans = ' '.join(self.player.clantags) if len(self.player.clantags) > 0 : self.playerName = FormattedText([ ('#ffffff', player.aspect['name']), ('', ' '), ('#cc00cc', self.playerClans, "utf-8"), ]) else: self.playerClans = self.playerName = FormattedText([ ('#ffffff', player.aspect['name']), ]) if customCurrency == None: self.currency = "dollars" else: self.currency = customCurrency self.result = None self.buySellRadiosRows = [] self.listOfItems = [] self.populateBuySellRadios() # declares self.buySellRadios self.currentRadios = self.buySellRadios self.rightWindowDescription = self.buySellRadios.description # description is whataver is in the description box on the right self.requestingConfirmation = False self.playerIs = "at buy/sell menu" self.bindings = KeyBindings() self.bindings.add('right' )(focus_next) self.bindings.add('tab' )(focus_next) self.bindings.add('s-tab')(focus_previous) self.bindings.add('left')(focus_previous) self.bindings.add('c-m')(self.handleEnter) self.bindings.add('escape')(self.handleEscape) self.style = Style.from_dict({ 'dialog.body': 'bg:#000000 #ffcccc', #background color, text color }) self.application = Application( layout=Layout( self.getShopContainer(), focused_element=self.buySellRadios, ), key_bindings=self.bindings, style=self.style, mouse_support=True, full_screen=True, ) def handleEscape(self, event): self.requestingConfirmation = False if self.currentRadios == self.buySellRadios: self.done() else: # return to main page self.playerIs = "at buy/sell menu" self.populateBuySellRadios() self.currentRadios = self.buySellRadios # self.description = self.buySellRadios.description self.refresh() def handleEnter(self, event): if self.requestingConfirmation: self.requestingConfirmation = False if self.playerIs == "buying": self.buy() self.listOfItems = self.shopInventory elif self.playerIs == "selling": self.sell() self.listOfItems = self.player.getAllInventoryItemsAsObjectList() if self.handleEmptiness(self.listOfItems): return self.makeListCurrentRadios(self.listOfItems) # TODO sound music, sound effect of eating a consumable return elif self.currentRadios == self.buySellRadios: # if on main page if self.currentRadios._selected_index == 0: # BUY, show shops inventory self.playerIs = "buying" self.listOfItems = self.shopInventory elif self.currentRadios._selected_index == 1: # SELL, show player inventory self.playerIs = "selling" self.listOfItems = self.player.getAllInventoryItemsAsObjectList() else:log("what the f**k") if self.handleEmptiness(self.listOfItems): return self.makeListCurrentRadios(self.listOfItems) elif self.currentRadios == self.selectedRadios: # if not on main page self.requestingConfirmation = True price = self.getCurrentlySelectedItem().sellValue if price == 1 and self.currency.endswith('s'): currency = 'dollar' else: currency = self.currency nameOfItem = self.getCurrentlySelectedItem().name if self.playerIs == "buying": self.refresh(setDescription="Purchase " + str(nameOfItem) +" for " + str(price) + " " + currency + "?") elif self.playerIs == "selling": self.refresh(setDescription="Sell " + str(nameOfItem) +" for " + str(price) + " " + currency + "?") def buy(self): item = self.getCurrentlySelectedItem() if item.sellValue > self.player.money: self.refresh(setDescription="You can't afford that.") else: self.player.money = self.player.money - item.sellValue # subtract funds self.player.money = round(self.player.money, 2) # round to cents item.sellValue = item.sellValue /2 # half the worth of the item after buying self.shopInventory.remove(item) self.player.addToInventory(item, printAboutIt=False) def sell(self): item = self.getCurrentlySelectedItem() if item.equipped == True: self.player.unequip(item=item) self.player.inventory.remove(item) # remove item from player inventory self.player.money = self.player.money + item.sellValue # get paid self.player.money = round(self.player.money, 2) # round just in case self.shopInventory.append(item) # give item to shop owner def getCurrentlySelectedItem(self): return self.listOfItems[self.currentRadios._selected_index] def handleEmptiness(self, lis): if len(self.listOfItems) == 0: self.currentRadios = self.buySellRadios if self.playerIs == "buying": self.playerIs = "at buy/sell menu" self.refresh(setDescription="Sold out!") elif self.playerIs == "selling": self.playerIs = "at buy/sell menu" self.refresh(setDescription="You've got nothing left!") return True def makeListCurrentRadios(self, lisp, selectedIndex=0): lisp = self.refreshItemDescriptions(lisp) self.listOfItemsTupled = self.tuplify(lisp) self.selectedRadios = RadioList2( values=self.listOfItemsTupled, app = self) self.selectedRadios._selected_index = selectedIndex self.currentRadios = self.selectedRadios # self.description = self.currentRadios.values[selectedIndex] self.refresh() def refreshItemDescriptions(self, lis): for i in lis: i.description = i.buildItemDescriptionString() return lis def tuplify(self, listt): if len(listt) == 0: return [] # should never see this newlist=[] for i in range(len(listt)): l = [] l.append(self.unicodify(listt[i].description)) l.append(self.unicodify(colorItem(listt[i], useGetName=True))) # colors newlist.append( tuple(l) ) return newlist def refresh(self, setDescription=False): index = self.currentRadios._selected_index if setDescription: self.rightWindowDescription = setDescription else: self.rightWindowDescription = self.currentRadios.values[index][0] self.application.layout=Layout( self.getShopContainer(), focused_element=self.currentRadios) def populateBuySellRadios(self): self.buySellRadiosRows = [] self.populateBuySellRadiosHelper('Buy') self.populateBuySellRadiosHelper('Sell') self.buySellRadios = RadioList2( values=self.buySellRadiosRows, app = self) def populateBuySellRadiosHelper(self, category): desc = self.shopKeeperAsciiArt tup = [] tup.append(desc) tup.append(category.capitalize()) self.buySellRadiosRows.append( tuple(tup) ) def unicodify(self, text): if isinstance(text, str): return str(text) else: return text def getShopContainer(self): width = 40 smallerWidth = 30 statsWidth = 20 height = 10 if self.playerIs == "at buy/sell menu": leftWindowTitle = "" descriptionArea =makeFormattedText(self.name) desc = self.rightWindowDescription elif self.playerIs == "buying": leftWindowTitle = makeFormattedText(self.name) descriptionArea = colorItem(self.getCurrentlySelectedItem()) desc = wrap(self.rightWindowDescription, width-2) elif self.playerIs == "selling": leftWindowTitle = makeFormattedText(self.player.aspect["name"]) descriptionArea = colorItem(self.getCurrentlySelectedItem()) desc = wrap(self.rightWindowDescription, width-2) root_container = VSplit([ HSplit([ Dialog( title=leftWindowTitle, body=HSplit([ self.currentRadios, ], ) ), ], padding=0, width = smallerWidth, ), HSplit([ Dialog( title = descriptionArea, body=Label(desc), ), ], padding=0, width = width,), HSplit([ Dialog( title = makeFormattedText("Stats"), body=Label(getStats(self.player)), ), ], padding=0, width = statsWidth, height= height,), ]) return root_container def run(self): self.application.run() def done(self): self.result = "hit escape" get_app().exit(result="hit escape") # TODO: # colors
def create_ipython_shortcuts(shell): """Set up the prompt_toolkit keyboard shortcuts for IPython""" kb = KeyBindings() insert_mode = vi_insert_mode | emacs_insert_mode if getattr(shell, 'handle_return', None): return_handler = shell.handle_return(shell) else: return_handler = newline_or_execute_outer(shell) kb.add('enter', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode ))(return_handler) kb.add('c-\\')(force_exit) kb.add('c-p', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)) )(previous_history_or_previous_completion) kb.add('c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)) )(next_history_or_next_completion) kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions) )(dismiss_completion) kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer) kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer) supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP')) kb.add('c-z', filter=supports_suspend)(suspend_to_bg) # Ctrl+I == Tab kb.add('tab', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode & cursor_in_leading_ws ))(indent_buffer) kb.add('c-o', filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode))(newline_autoindent_outer(shell.input_splitter)) kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor) if shell.display_completions == 'readlinelike': kb.add('c-i', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode & ~cursor_in_leading_ws ))(display_completions_like_readline) if sys.platform == 'win32': kb.add('c-v', filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste) return kb
class CombatUI(): def __init__(self, player, enemy, song='worry 2.wav'): self.song = Sound( player,fileName = song, loop=-1) self.player = player self.playerClans = ' '.join(self.player.clantags) if len(self.player.clantags) > 0 : self.playerName = FormattedText([ ('#ffffff', str(player.aspect['name'])), ('', ' '), ('#cc00cc', str(self.playerClans)), ]) else: self.playerClans = self.playerName = FormattedText([ ('#ffffff', str(player.aspect['name'])), ]) self.enemy = enemy self.playerGoesNext = True # by default, enemy always gets first strike self.playerJustDodged = False self.escapeTries = 0 self.escapeChance = .3 self.battleLog = '\n\n\n\n\n\n' self.maxHeightOfBattleLogWindow = 7 self.totalWidth = 90 self.actionsWidth = 30 self.statsWidth = 20 self.selectedIndexText = '' self.result = None self.playerHPBar = ProgressBar() self.setHealthProgressBar(self.playerHPBar, self.toPercent(self.player.hp, self.player.maxhp)) self.enemyHPBar = ProgressBar() self.setHealthProgressBar(self.enemyHPBar, 100) self.radios = RadioList( values=[ #value, lable ('Attack', 'Attack'), # use eqipped weapon ('Dodge', 'Dodge'), # icrease miss chance for enemy ('Item', 'Item'), ('Run', 'Run') # try to escape # more options could be: # check - returns text about enemy potentially indicating weaknessess ], player = self.player, width = self.actionsWidth) self.bindings = KeyBindings() self.bindings.add('right' )(focus_next) self.bindings.add('tab' )(focus_next) self.bindings.add('s-tab')(focus_previous) self.bindings.add('left')(focus_previous) self.bindings.add('c-m')(self.handleEnter) self.bindings.add('escape')(self.tryToEscape) # self.bindings.add('up')(self.setSelectedIndexTextUp) # TODO: make secret easter egg key bindings # self.bindings.add('a', 'a')(self.test) self.style = Style.from_dict({ 'dialog.body': 'bg:#000000 #ffcccc', #background color, text color }) self.application = Application( layout=Layout( self.getRootContainer(), focused_element=self.radios, ), key_bindings=self.bindings, style=self.style, mouse_support=True, full_screen=True, ) # call this function to change the value a progress bar (prog) to a percent def setHealthProgressBar(self,progbar, percent): if percent < 0: # should never happen but for safety percent = 0 progbar.container = FloatContainer( content=Window(height=1), floats=[ Float(left=0, top=0, right=0, bottom=0, content=VSplit([ Window(style='bg:#00cc00', # health, green width=lambda: D(weight=int(percent))), Window(style='bg:#ff0000', # damage, red width=lambda: D(weight=int(100 - percent))), ])), ]) def toPercent(self, value, max): return int(100*(float(value)/float(max))) def handleEnter(self, event): if not self.playerGoesNext: # check if it's actually your turn return self.playerGoesNext = False choice = self.radios.values[self.radios._selected_index][0] s = '' if choice == "Attack": self.attackEnemy() return # return early so attackEnemy can go to enemy turn so damaging consunmables work elif choice == "Dodge": # dodging increases chance for enemy to miss by 30% SCALING s += "You tried to dodge... " self.playerJustDodged = True elif choice == "Item": # doesnt take your turn self.playerGoesNext = True self.done(result='inventory') return elif choice == "Run": s += self.tryToEscape() else: s += "How did you do that!?" self.enemyTurn(s) def attackEnemy(self, alwaysHit=True, consumableDamage=None, consumableName=None ): s = '' if not consumableDamage == None: # if has consumable damage damage = consumableDamage # better also have a name s += "You threw the " + str(consumableName) + "... " else: s += "You tried to attack... " damage = self.player.getTotalAttackPower() s += " and did " s += str(damage) s += " damage!" # TODO color self.enemy.hp = self.enemy.hp - int(damage) if self.enemy.hp < 0: self.enemy.hp = 0 self.setHealthProgressBar(self.enemyHPBar, self.toPercent(self.enemy.hp, self.enemy.maxhp)) self.enemyTurn(s) def tryToEscape(self, event=None): s = '' s += "You tried to run..." randomChance = random.uniform(0,1) - (self.escapeTries-1) *.1 # each try makes it 10 percent easier to escape after first try if self.escapeChance > randomChance and self.escapeTries>0: #has to have already tried to escape once s += " and escaped the combat!" # TODO advanced combat: isnt ever visible self.done("escaped") else: s += " but failed to escape!" self.escapeTries += 1 return s def enemyTurn(self, textOfPlayerTurn=False): if self.enemy.hp == 0: # check if he dead self.done("win") return # for now, always try to attack TODO advanced combat self.playerGoesNext = True s='' s += self.enemy.name + " tried to " attack = self.enemy.getRandomAttack() if attack[-1] == "*": # if attack finishes the sentence s += attack[:-1] # remove * else : s += str(attack) s += " you... " # calculate hit chance and handle dodgeModifier = 0 # TODO advanced combat dodge modifier if self.playerJustDodged == True: dodgeModifier = 30 self.playerJustDodged = False if self.enemy.missChancePercent + dodgeModifier > random.randint(0,100): # missed if not attack[-1] == "*": s += " but missed!" else: s += " But missed!" else: # hit damage = self.enemy.attack if not attack[-1] == "*": s += " and dealt " + str(damage) + " damage!" else: s += " It dealt " + str(damage) + " damage!" self.player.hp = self.player.hp - damage # lose health #t1 = threading.Thread(target=self.rollNumbers(self.player.hp, self.player.hp - damage), args=()) #t1.start() # self.rollNumbers(self.player.hp, self.player.hp - damage) if self.player.hp < 0: self.player.hp = 0 self.setHealthProgressBar(self.playerHPBar, self.toPercent(self.player.hp, self.player.maxhp)) if self.player.hp == 0: #dead # TODO make death less awkwawrd self.done("lose") return if textOfPlayerTurn: self.battleLog = textOfPlayerTurn + '\n\n' + s else: self.battleLog = s self.refresh() def rollNumbers(self, start, end, speed=1.5): r = start-end # range maxSpeed = .01 if r < 0: r *= -1 startTime = .5 for t in range(r): startTime /= speed time = startTime for c in range(r+1): s = int(start - c ) self.player.hp = s self.refresh() if time < maxSpeed: wait(maxSpeed) else: wait(time) time *= speed def refresh(self): self.fillBattleLogWithNewlines() self.application.layout=Layout( self.getRootContainer(), focused_element=self.radios) def fillBattleLogWithNewlines(self): self.battleLog = wrap(self.battleLog, limit=self.totalWidth-self.actionsWidth-self.statsWidth) slicedBattleLog = self.battleLog.split('\n') # list of rows of the battlelog while True: if len(slicedBattleLog) < self.maxHeightOfBattleLogWindow: slicedBattleLog.append('\n') else: break self.battleLog = '\n'.join(slicedBattleLog) # def suspense(self): # doesnt work because ui updates on run method, not during other methods # for i in range(3): # wait(.5) # self.battleLog += '.' # self.refresh() def makeFormattedText(self, text, color='#ffffff'): return FormattedText([ (color, str(text)) ]) # returns new root container (updates text and stuff) def getRootContainer(self): height = self.maxHeightOfBattleLogWindow enemyName = self.makeFormattedText(self.enemy.name) battleLogTitle = FormattedText([ ('#ffffff', "Battle Log") ]) actionsTitle = FormattedText([ ('#ffffff', "Actions") ]) statsTitle = FormattedText([ ('#ffffff', "Stats") ]) root_container = HSplit([ VSplit([ Dialog( # actions title=actionsTitle, body=HSplit([ self.radios, ], height= height), width=self.actionsWidth ), # battlelog Dialog( title = battleLogTitle, body=Label(self.battleLog), width=self.totalWidth-self.actionsWidth - self.statsWidth ), Dialog( # stats title = statsTitle, body=Label(getStats(self.player)), width=self.statsWidth , ), ], padding=0, width = self.actionsWidth, height=height+2 ), # health bars # VSplit([ Frame( body=self.playerHPBar, title=self.playerName, width=int(self.totalWidth/2) ), Frame( body=self.enemyHPBar, title=enemyName, width=int(self.totalWidth/2) ), ], padding=0, width = self.totalWidth) ]) return root_container def run(self): self.application.run() def done(self, result='?'): self.result = result if self.result != 'inventory': self.song.stopSound() get_app().exit(result=self.result)
def handle_blueprints(): """Entrypoint for first interaction with user. Ask user to choose type of pypackage. NOTE: We're using python-prompt-toolkit which is both powerful and complicated, so we try to document its use asmuch as possible. """ ############################################################################ # LIST OF BLUEPRINTS ############################################################################ # Here we list out all possible blueprints we have that will be presented # as checkboxes. blueprint_order = ['auth', 'database'] blueprints = { 'auth': Checkbox(text='Authentication against LDAP'), 'database': Checkbox(text='Database'), } blueprint_checkboxes = [] for bp in blueprint_order: blueprints[bp].checked = False blueprint_checkboxes.append(blueprints[bp]) ############################################################################ # KEY BINDINGS ############################################################################ # Key bindings for this applications: # * radio buttons use inbuilt key-bindings of up and down arrows for focus and enter for selection. # * tab and shift tab bindings to shift focus from one frame to the next. bindings = KeyBindings() bindings.add(Keys.Down)(focus_next) bindings.add(Keys.Tab)(focus_next) bindings.add(Keys.Up)(focus_previous) bindings.add(Keys.BackTab)(focus_previous) # CTRL-C to quit the prompt-app. @bindings.add('c-c') def exit_c(event): """Ctrl-C to quit.""" event.app.exit(result=False) # End App. def exit_app(): get_app().exit(result=True) ############################################################################ # Actually application container. ############################################################################ # We use VSplit to not utilize the entire width of the window. root_container = VSplit([ HSplit([ Frame(title='Choose which blueprints do you want?', body=HSplit(children=blueprint_checkboxes), width=80), Button('Done', handler=exit_app) ], padding=1), ]) layout = Layout(root_container) app = Application(layout=layout, key_bindings=bindings, full_screen=False) ############################################################################ # Actually application container. ############################################################################ # print(blueprints_doc) result = app.run() if result: blueprint_options = {} for blueprint_name, blueprint_checkbox in blueprints.items(): if blueprint_checkbox.checked: blueprint_handler = blueprint_handlers[blueprint_name] blueprint_options[blueprint_name] = blueprint_handler( include=True) else: blueprint_options[blueprint_name] = {'include': False} return blueprint_options else: print("Aborted!") sys.exit(0) return blueprint_options
class UserInterface: def __init__(self, config: Configuration): self.config = config self.tomato = Tomato(self.config) self.prev_hash = None self._create_ui() def _create_ui(self): btn_start = Button("Start", handler=self.tomato.start) btn_pause = Button("Pause", handler=self.tomato.pause) btn_reset = Button("Reset", handler=self.tomato.reset) btn_reset_all = Button("Reset All", handler=self.tomato.reset_all) btn_exit = Button("Exit", handler=self._exit_clicked) # All the widgets for the UI. self.text_area = FormattedTextControl(focusable=False, show_cursor=False) text_window = Window( content=self.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, ]), ])) layout = Layout(container=root_container, focused_element=btn_start) self._set_key_bindings() # Styling. style = Style([ ("left-pane", "bg:#888800 #000000"), ("right-pane", "bg:#00aa00 #000000"), ("button", "#000000"), ("button-arrow", "#000000"), ("button focused", "bg:#ff0000"), ("red", "#ff0000"), ("green", "#00ff00"), ]) self.application = Application(layout=layout, key_bindings=self.kb, style=style, full_screen=True) def _set_key_bindings(self): self.kb = KeyBindings() actions = { "focus_next": focus_next, "focus_previous": focus_previous, "exit_clicked": self._exit_clicked, "start": lambda _=None: self.tomato.start(), "pause": lambda _=None: self.tomato.pause(), "reset": lambda _=None: self.tomato.reset(), "reset_all": lambda _=None: self.tomato.reset_all(), } for action, keys in self.config.key_bindings.items(): for key in keys.split(","): try: self.kb.add(key.strip())(actions[action]) except KeyError: pass @staticmethod def _exit_clicked(_=None): get_app().exit() def _draw(self): self.tomato.update() text, hash_ = self.tomato.render() # WHY: Avoid unnecessary updates if hash_ != self.prev_hash: self.text_area.text = text self.application.invalidate() self.prev_hash = hash_ def run(self): self._draw() threading.Thread(target=lambda: every(0.4, self._draw), daemon=True).start() self.application.run()
#!/usr/bin/env python # vim: set fileencoding=utf-8 from prompt_toolkit import Application from prompt_toolkit.layout import Layout, HSplit, VSplit from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous from prompt_toolkit.application.current import get_app from prompt_toolkit.widgets import * # napojenà na klávesové zkratky key_bindings = KeyBindings() key_bindings.add("s-tab")(focus_previous) key_bindings.add("tab")(focus_next) def message(msg): text_area.text += msg + "\n" @key_bindings.add("c-n") def on_new_selected(event=None): message("'New' menu item selected") @key_bindings.add("c-o") def on_open_selected(event=None): message("'Open' menu item selected")
def is_yearly_view(): return dataview.active_view in ['yearly'] @Condition def is_not_yearly_view(): return not dataview.active_view in ['yearly'] @Condition def not_showing_details(): return dataview.is_showing_details == False @Condition def is_showing_details(): return dataview.is_showing_details bindings.add('tab', filter=is_not_editing)(focus_next) bindings.add('s-tab', filter=is_not_editing)(focus_previous) @bindings.add('l', filter=is_viewing) def do_go_to_line(*event): def coroutine(): default = '' if dataview.current_row: default = dataview.current_row + 1 dialog = TextInputDialog( title='Go to line', label_text='Line number:', default=str(default)) line_number = yield From(show_dialog_as_float(dialog))
def _get_bindings(self): bindings = KeyBindings() bindings.add("c-c")(lambda event: self._interrupt_handler(event)) return bindings
MenuItem('Status Bar'), ]), MenuItem('Info', children=[ MenuItem('About'), ]), ], floats=[ Float(xcursor=True, ycursor=True, content=CompletionsMenu( max_height=16, scroll_offset=1)), ]) # Global key bindings. bindings = KeyBindings() bindings.add('tab')(focus_next) bindings.add('s-tab')(focus_previous) style = Style.from_dict({ 'window.border': '#888888', 'shadow': 'bg:#222222', 'menu-bar': 'bg:#aaaaaa #888888', 'menu-bar.selected-item': 'bg:#ffffff #000000', 'menu': 'bg:#888888 #ffffff', 'menu.border': '#aaaaaa', 'window.border shadow': '#444444', 'focused button': 'bg:#880000 #ffffff noinherit',
def ui_table(): print(table_header) ############################################################################ # SETUP BINDINGS ############################################################################ bindings = KeyBindings() bindings.add(Keys.Tab)(focus_next) bindings.add(Keys.Enter)(focus_next) bindings.add(Keys.BackTab)(focus_previous) # CTRL-C to quit the prompt-app. @bindings.add('c-c') def exit_c(event): """Ctrl-C to quit.""" event.app.exit(result=False) def table_done(): get_app().exit(result="table_done") ############################################################################ # TABLE DETAILS ############################################################################ table_name = TextArea(prompt='table_name : ', multiline=False) column_names = TextArea(prompt='column_names (comma separated): ', multiline=False) unique_columns = TextArea(prompt='collectively unique columns : ', multiline=False) root_container = VSplit( width=80, children=[ HSplit( padding=1, children=[ Frame( title='Database Table Details:', body=HSplit( width=80, children=[ table_name, column_names, unique_columns, ] ), ), VSplit( children=[ Button('Done', handler=table_done, width=80), ], ), ], ), ] ) layout = Layout(root_container) app = Application(layout=layout, key_bindings=bindings, full_screen=False) table_status = app.run() if not table_status: abort() return (table_status, table_name.text, column_names.text, unique_columns.text)
class InventoryUI(): def __init__(self, player): self.player = player self.playerClans = ' '.join(self.player.clantags) if len(self.player.clantags) > 0 : self.playerName = FormattedText([ ('#ffffff', player.aspect['name']), ('', ' '), ('#cc00cc', self.playerClans, "utf-8"), ]) else: self.playerClans = self.playerName = FormattedText([ ('#ffffff', player.aspect['name']), ]) self.result = None self.mainRadiosRows = [] self.listOfItems = [] self.populateMainRadios() # declares self.mainRadios self.currentRadios = self.mainRadios self.description = self.mainRadios.description # description is whataver is in the description box on the right self.requestingConfirmation = False self.bindings = KeyBindings() self.bindings.add('right' )(focus_next) self.bindings.add('tab' )(focus_next) self.bindings.add('s-tab')(focus_previous) self.bindings.add('left')(focus_previous) self.bindings.add('c-m')(self.handleEnter) self.bindings.add('escape')(self.handleEscape) self.style = Style.from_dict({ 'dialog.body': 'bg:#000000 #ffcccc', #background color, text color }) self.application = Application( layout=Layout( self.getRootContainer(), focused_element=self.mainRadios, ), key_bindings=self.bindings, style=self.style, mouse_support=True, full_screen=True, ) def handleEscape(self, event): self.requestingConfirmation = False if self.currentRadios == self.mainRadios: self.done() else: # return to main page self.populateMainRadios() self.currentRadios = self.mainRadios # self.description = self.mainRadios.description self.refresh() def handleEnter(self, event): if self.requestingConfirmation: self.requestingConfirmation = False result = self.player.activateItem(self.getCurrentlySelectedItem()) if not isinstance(result, str): # if result isnt a string self.done(result)# this should be different self.updateListOfItems() self.makeListCurrentRadios(self.listOfItems) self.refresh(setDescription=result) # TODO sound music, sound effect of eating a consumable return if self.currentRadios == self.mainRadios: # if on main page self.updateListOfItems() self.makeListCurrentRadios(self.listOfItems) elif self.currentRadios == self.selectedRadios: # if not on main page currentItem = self.listOfItems[self.currentRadios._selected_index] if currentItem.type == "consumable": if currentItem.consumable.consumableType == 'xp': description = 'Eat it?' elif currentItem.consumable.consumableType == 'damage': description = 'Throw it?' elif currentItem.consumable.consumableType == 'heal': description = 'Eat it?' else: description = 'Crash the game?' # shouldnt ever see self.requestingConfirmation = True self.refresh(setDescription=description) return self.player.activateItem(self.listOfItems[self.currentRadios._selected_index]) # can delete items self.makeListCurrentRadios(self.listOfItems,self.selectedRadios._selected_index) def updateListOfItems(self): category = self.mainRadios.values[self.mainRadios._selected_index][1] if category == 'Weapons': self.listOfItems = self.player.getAllInventoryItemsAsObjectList(_type='weapon') elif category == 'Armour': self.listOfItems = self.player.getAllInventoryItemsAsObjectList(_type='armour') elif category == 'Consumable': self.listOfItems = self.player.getAllInventoryItemsAsObjectList(_type='consumable') elif category == 'Quest': self.listOfItems = self.player.getAllInventoryItemsAsObjectList(_type='quest') elif category == 'Misc': self.listOfItems = self.player.getAllInventoryItemsAsObjectList(_type='misc') if len(self.listOfItems) == 0: self.populateMainRadios() self.currentRadios = self.mainRadios self.refresh() def makeListCurrentRadios(self, lisp, selectedIndex=0): if len(lisp) == 0: self.populateMainRadios() self.currentRadios = self.mainRadios else: lisp = self.refreshItemDescriptions(lisp) self.listOfItemsTupled = self.tuplify(lisp) self.selectedRadios = RadioList2( values=self.listOfItemsTupled, app = self) self.selectedRadios._selected_index = selectedIndex self.currentRadios = self.selectedRadios # self.description = self.currentRadios.values[selectedIndex] self.refresh() def refreshItemDescriptions(self, lis): for i in lis: i.description = i.buildItemDescriptionString() return lis def tuplify(self, listt): if len(listt) == 0: return [] # should never see this newlist=[] for i in listt: l = [] l.append(self.unicodify(i.description)) l.append(self.unicodify(colorItem(i, useGetName=True))) # colors newlist.append( tuple(l) ) return newlist def refresh(self, setDescription=False): index = self.currentRadios._selected_index if setDescription: self.description = setDescription else: self.description = self.currentRadios.values[index][0] self.application.layout=Layout( self.getRootContainer(), focused_element=self.currentRadios) def populateMainRadios(self): self.mainRadiosRows = [] self.populateMainRadiosHelper('weapon') self.populateMainRadiosHelper('armour') self.populateMainRadiosHelper('consumable') self.populateMainRadiosHelper('quest') self.populateMainRadiosHelper('misc') self.mainRadios = RadioList2( values=self.mainRadiosRows, app = self) def populateMainRadiosHelper(self, category): s = self.unicodify(self.player.getAllInventoryItemsAsString(_type=category, showEquipped=True)) if not s == '': tup = [] tup.append(s) if category == 'weapon': tup.append('Weapons') else: tup.append(category.capitalize()) self.mainRadiosRows.append( tuple(tup) ) def unicodify(self, text): if isinstance(text, str): return str(text) else: return text def getCurrentlySelectedItem(self): return self.listOfItems[self.currentRadios._selected_index] # returns new root container (updates text and stuff) def getRootContainer(self): statsWidth = 20 largerWidth = 40 smallerWidth = 30 if self.currentRadios != self.mainRadios: descriptionTitle = colorItem(self.getCurrentlySelectedItem()) else: descriptionTitle = FormattedText([('#ffffff', "Description")]) actionsTitle = FormattedText([('#ffffff', "Inventory")]) stats = FormattedText([('#ffffff', "Stats")]) desc = wrap(self.description, largerWidth-2) root_container = VSplit([ HSplit([ Dialog( title=actionsTitle, body=HSplit([ self.currentRadios, ], ) ), ], padding=0, width = smallerWidth, ), HSplit([ Dialog( title = descriptionTitle, body=Label(desc), ), ], padding=0, width = largerWidth, ), HSplit([ Dialog( title = stats, body=Label(getStats(self.player)), ), ], padding=0, width=statsWidth ), ]) return root_container def run(self): self.application.run() def done(self, result="hit escape"): self.result = result get_app().exit(result=self.result) # TODO: # colors
def create_ipython_shortcuts(shell): """Set up the prompt_toolkit keyboard shortcuts for IPython""" kb = KeyBindings() insert_mode = vi_insert_mode | emacs_insert_mode if getattr(shell, 'handle_return', None): return_handler = shell.handle_return(shell) else: return_handler = newline_or_execute_outer(shell) kb.add('enter', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode))(return_handler) def reformat_and_execute(event): reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell) event.current_buffer.validate_and_handle() kb.add('escape', 'enter', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode))(reformat_and_execute) kb.add('c-\\')(force_exit) kb.add('c-p', filter=( vi_insert_mode & has_focus(DEFAULT_BUFFER)))(previous_history_or_previous_completion) kb.add( 'c-n', filter=(vi_insert_mode & has_focus(DEFAULT_BUFFER)))(next_history_or_next_completion) kb.add('c-g', filter=(has_focus(DEFAULT_BUFFER) & has_completions))(dismiss_completion) kb.add('c-c', filter=has_focus(DEFAULT_BUFFER))(reset_buffer) kb.add('c-c', filter=has_focus(SEARCH_BUFFER))(reset_search_buffer) supports_suspend = Condition(lambda: hasattr(signal, 'SIGTSTP')) kb.add('c-z', filter=supports_suspend)(suspend_to_bg) # Ctrl+I == Tab kb.add('tab', filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode & cursor_in_leading_ws))(indent_buffer) kb.add('c-o', filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode))( newline_autoindent_outer(shell.input_transformer_manager)) kb.add('f2', filter=has_focus(DEFAULT_BUFFER))(open_input_in_editor) @Condition def auto_match(): return shell.auto_match focused_insert = (vi_insert_mode | emacs_insert_mode) & has_focus(DEFAULT_BUFFER) _preceding_text_cache = {} _following_text_cache = {} def preceding_text(pattern): try: return _preceding_text_cache[pattern] except KeyError: pass m = re.compile(pattern) def _preceding_text(): app = get_app() return bool( m.match( app.current_buffer.document.current_line_before_cursor)) condition = Condition(_preceding_text) _preceding_text_cache[pattern] = condition return condition def following_text(pattern): try: return _following_text_cache[pattern] except KeyError: pass m = re.compile(pattern) def _following_text(): app = get_app() return bool( m.match(app.current_buffer.document.current_line_after_cursor)) condition = Condition(_following_text) _following_text_cache[pattern] = condition return condition # auto match @kb.add("(", filter=focused_insert & auto_match & following_text(r"[,)}\]]|$")) def _(event): event.current_buffer.insert_text("()") event.current_buffer.cursor_left() @kb.add("[", filter=focused_insert & auto_match & following_text(r"[,)}\]]|$")) def _(event): event.current_buffer.insert_text("[]") event.current_buffer.cursor_left() @kb.add("{", filter=focused_insert & auto_match & following_text(r"[,)}\]]|$")) def _(event): event.current_buffer.insert_text("{}") event.current_buffer.cursor_left() @kb.add( '"', filter=focused_insert & auto_match & preceding_text(r'^([^"]+|"[^"]*")*$') & following_text(r"[,)}\]]|$"), ) def _(event): event.current_buffer.insert_text('""') event.current_buffer.cursor_left() @kb.add( "'", filter=focused_insert & auto_match & preceding_text(r"^([^']+|'[^']*')*$") & following_text(r"[,)}\]]|$"), ) def _(event): event.current_buffer.insert_text("''") event.current_buffer.cursor_left() # raw string @kb.add("(", filter=focused_insert & auto_match & preceding_text(r".*(r|R)[\"'](-*)$")) def _(event): matches = re.match( r".*(r|R)[\"'](-*)", event.current_buffer.document.current_line_before_cursor, ) dashes = matches.group(2) or "" event.current_buffer.insert_text("()" + dashes) event.current_buffer.cursor_left(len(dashes) + 1) @kb.add("[", filter=focused_insert & auto_match & preceding_text(r".*(r|R)[\"'](-*)$")) def _(event): matches = re.match( r".*(r|R)[\"'](-*)", event.current_buffer.document.current_line_before_cursor, ) dashes = matches.group(2) or "" event.current_buffer.insert_text("[]" + dashes) event.current_buffer.cursor_left(len(dashes) + 1) @kb.add("{", filter=focused_insert & auto_match & preceding_text(r".*(r|R)[\"'](-*)$")) def _(event): matches = re.match( r".*(r|R)[\"'](-*)", event.current_buffer.document.current_line_before_cursor, ) dashes = matches.group(2) or "" event.current_buffer.insert_text("{}" + dashes) event.current_buffer.cursor_left(len(dashes) + 1) # just move cursor @kb.add(")", filter=focused_insert & auto_match & following_text(r"^\)")) @kb.add("]", filter=focused_insert & auto_match & following_text(r"^\]")) @kb.add("}", filter=focused_insert & auto_match & following_text(r"^\}")) @kb.add('"', filter=focused_insert & auto_match & following_text('^"')) @kb.add("'", filter=focused_insert & auto_match & following_text("^'")) def _(event): event.current_buffer.cursor_right() @kb.add( "backspace", filter=focused_insert & preceding_text(r".*\($") & auto_match & following_text(r"^\)"), ) @kb.add( "backspace", filter=focused_insert & preceding_text(r".*\[$") & auto_match & following_text(r"^\]"), ) @kb.add( "backspace", filter=focused_insert & preceding_text(r".*\{$") & auto_match & following_text(r"^\}"), ) @kb.add( "backspace", filter=focused_insert & preceding_text('.*"$') & auto_match & following_text('^"'), ) @kb.add( "backspace", filter=focused_insert & preceding_text(r".*'$") & auto_match & following_text(r"^'"), ) def _(event): event.current_buffer.delete() event.current_buffer.delete_before_cursor() if shell.display_completions == "readlinelike": kb.add( "c-i", filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode & ~cursor_in_leading_ws), )(display_completions_like_readline) if sys.platform == "win32": kb.add("c-v", filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste) @Condition def ebivim(): return shell.emacs_bindings_in_vi_insert_mode focused_insert_vi = has_focus(DEFAULT_BUFFER) & vi_insert_mode # Needed for to accept autosuggestions in vi insert mode def _apply_autosuggest(event): b = event.current_buffer suggestion = b.suggestion if suggestion: b.insert_text(suggestion.text) else: nc.end_of_line(event) @kb.add("end", filter=has_focus(DEFAULT_BUFFER) & (ebivim | ~vi_insert_mode)) def _(event): _apply_autosuggest(event) @kb.add("c-e", filter=focused_insert_vi & ebivim) def _(event): _apply_autosuggest(event) @kb.add("c-f", filter=focused_insert_vi) def _(event): b = event.current_buffer suggestion = b.suggestion if suggestion: b.insert_text(suggestion.text) else: nc.forward_char(event) @kb.add("escape", "f", filter=focused_insert_vi & ebivim) def _(event): b = event.current_buffer suggestion = b.suggestion if suggestion: t = re.split(r"(\S+\s+)", suggestion.text) b.insert_text(next((x for x in t if x), "")) else: nc.forward_word(event) # Simple Control keybindings key_cmd_dict = { "c-a": nc.beginning_of_line, "c-b": nc.backward_char, "c-k": nc.kill_line, "c-w": nc.backward_kill_word, "c-y": nc.yank, "c-_": nc.undo, } for key, cmd in key_cmd_dict.items(): kb.add(key, filter=focused_insert_vi & ebivim)(cmd) # Alt and Combo Control keybindings keys_cmd_dict = { # Control Combos ("c-x", "c-e"): nc.edit_and_execute, ("c-x", "e"): nc.edit_and_execute, # Alt ("escape", "b"): nc.backward_word, ("escape", "c"): nc.capitalize_word, ("escape", "d"): nc.kill_word, ("escape", "h"): nc.backward_kill_word, ("escape", "l"): nc.downcase_word, ("escape", "u"): nc.uppercase_word, ("escape", "y"): nc.yank_pop, ("escape", "."): nc.yank_last_arg, } for keys, cmd in keys_cmd_dict.items(): kb.add(*keys, filter=focused_insert_vi & ebivim)(cmd) def get_input_mode(self): app = get_app() app.ttimeoutlen = shell.ttimeoutlen app.timeoutlen = shell.timeoutlen return self._input_mode def set_input_mode(self, mode): shape = {InputMode.NAVIGATION: 2, InputMode.REPLACE: 4}.get(mode, 6) cursor = "\x1b[{} q".format(shape) sys.stdout.write(cursor) sys.stdout.flush() self._input_mode = mode if shell.editing_mode == "vi" and shell.modal_cursor: ViState._input_mode = InputMode.INSERT ViState.input_mode = property(get_input_mode, set_input_mode) return kb
Box( body=Frame(text_area), padding=1, style='class:right-pane'), ]), ]), ) layout = Layout( container=root_container, focused_element=button1) # Key bindings. kb = KeyBindings() kb.add('tab')(focus_next) kb.add('s-tab')(focus_previous) # Styling. style = Style([ ('left-pane', 'bg:#888800 #000000'), ('right-pane', 'bg:#00aa00 #000000'), ('button', '#000000'), ('button-arrow', '#000000'), ('button focused', 'bg:#ff0000'), ('text-area focused', 'bg:#ff0000'), ]) # Build a main application object.
def main(): """Entrypoint for first interaction with user. Ask user to choose type of pypackage. NOTE: We're using python-prompt-toolkit which is both powerful and complicated, so we try to document its use asmuch as possible. """ ############################################################################ # LIST OF APPLICATIONS ############################################################################ # Here we list out all possible applications we have that will be presented # as radio buttons. package_radios = RadioList(values=[ # Tuple format: ("Why is this used? This is presented to the user.") ("package_simple", "Simple Python App"), # ("package_flask", "Simple Flask App"), ("package_blueprints", "Flask App with Blueprints"), ]) ############################################################################ # KEY BINDINGS ############################################################################ # Key bindings for this applications: # * radio buttons use key-bindings of up and down arrows for focus. (comes inbuilt) # * radio buttons use key-bindings of Enter to select. (comes inbuilt) # * tab and shift tab bindings to shift focus from one frame to the next. bindings = KeyBindings() bindings.add(Keys.Tab)(focus_next) bindings.add(Keys.BackTab)(focus_previous) # CTRL-C to quit the prompt-app. @bindings.add("c-c") def exit_c(event): """Ctrl-C to quit.""" event.app.exit(result=False) # End App. def exit_app(): get_app().exit(True) ############################################################################ # Actually application container. ############################################################################ # We use VSplit to not utilize the entire width of the window. root_container = VSplit([ HSplit( [ Frame( title="Choose which package-type do you want?", body=package_radios, width=80, ), Button("Done", handler=exit_app), ], padding=1, ) ]) layout = Layout(root_container) app = Application(layout=layout, key_bindings=bindings, full_screen=False) ############################################################################ # Actually application container. ############################################################################ print(main_doc) result = app.run() if result: cli_package.main(package_radios.current_value) else: print("Aborted!") sys.exit(0)
class PymuxKeyBindings(object): """ Pymux key binding manager. """ def __init__(self, pymux): self.pymux = pymux def get_search_state(): " Return the currently active SearchState. (The one for the focused pane.) " return pymux.arrangement.get_active_pane().search_state self.custom_key_bindings = KeyBindings() self.key_bindings = merge_key_bindings([ self._load_builtins(), self.custom_key_bindings, ]) self._prefix = ('c-b', ) self._prefix_binding = None # Load initial bindings. self._load_prefix_binding() # Custom user configured key bindings. # { (needs_prefix, key) -> (command, handler) } self.custom_bindings = {} def _load_prefix_binding(self): """ Load the prefix key binding. """ pymux = self.pymux # Remove previous binding. if self._prefix_binding: self.custom_key_bindings.remove_binding(self._prefix_binding) # Create new Python binding. @self.custom_key_bindings.add(*self._prefix, filter= ~(HasPrefix(pymux) | has_focus(COMMAND) | has_focus(PROMPT) | WaitsForConfirmation(pymux))) def enter_prefix_handler(event): " Enter prefix mode. " pymux.get_client_state().has_prefix = True self._prefix_binding = enter_prefix_handler @property def prefix(self): " Get the prefix key. " return self._prefix @prefix.setter def prefix(self, keys): """ Set a new prefix key. """ assert isinstance(keys, tuple) self._prefix = keys self._load_prefix_binding() def _load_builtins(self): """ Fill the Registry with the hard coded key bindings. """ pymux = self.pymux kb = KeyBindings() # Create filters. has_prefix = HasPrefix(pymux) waits_for_confirmation = WaitsForConfirmation(pymux) prompt_or_command_focus = has_focus(COMMAND) | has_focus(PROMPT) display_pane_numbers = Condition(lambda: pymux.display_pane_numbers) in_scroll_buffer_not_searching = InScrollBufferNotSearching(pymux) @kb.add(Keys.Any, filter=has_prefix) def _(event): " Ignore unknown Ctrl-B prefixed key sequences. " pymux.get_client_state().has_prefix = False @kb.add('c-c', filter=prompt_or_command_focus & ~has_prefix) @kb.add('c-g', filter=prompt_or_command_focus & ~has_prefix) # @kb.add('backspace', filter=has_focus(COMMAND) & ~has_prefix & # Condition(lambda: cli.buffers[COMMAND].text == '')) def _(event): " Leave command mode. " pymux.leave_command_mode(append_to_history=False) @kb.add('y', filter=waits_for_confirmation) @kb.add('Y', filter=waits_for_confirmation) def _(event): """ Confirm command. """ client_state = pymux.get_client_state() command = client_state.confirm_command client_state.confirm_command = None client_state.confirm_text = None pymux.handle_command(command) @kb.add('n', filter=waits_for_confirmation) @kb.add('N', filter=waits_for_confirmation) @kb.add('c-c' , filter=waits_for_confirmation) def _(event): """ Cancel command. """ client_state = pymux.get_client_state() client_state.confirm_command = None client_state.confirm_text = None @kb.add('c-c', filter=in_scroll_buffer_not_searching) @kb.add('enter', filter=in_scroll_buffer_not_searching) @kb.add('q', filter=in_scroll_buffer_not_searching) def _(event): " Exit scroll buffer. " pane = pymux.arrangement.get_active_pane() pane.exit_scroll_buffer() @kb.add(' ', filter=in_scroll_buffer_not_searching) def _(event): " Enter selection mode when pressing space in copy mode. " event.current_buffer.start_selection(selection_type=SelectionType.CHARACTERS) @kb.add('enter', filter=in_scroll_buffer_not_searching & has_selection) def _(event): " Copy selection when pressing Enter. " clipboard_data = event.current_buffer.copy_selection() event.app.clipboard.set_data(clipboard_data) @kb.add('v', filter=in_scroll_buffer_not_searching & has_selection) def _(event): " Toggle between selection types. " types = [SelectionType.LINES, SelectionType.BLOCK, SelectionType.CHARACTERS] selection_state = event.current_buffer.selection_state try: index = types.index(selection_state.type) except ValueError: # Not in list. index = 0 selection_state.type = types[(index + 1) % len(types)] @Condition def popup_displayed(): return self.pymux.get_client_state().display_popup @kb.add('q', filter=popup_displayed, eager=True) def _(event): " Quit pop-up dialog. " self.pymux.get_client_state().display_popup = False @kb.add(Keys.Any, eager=True, filter=display_pane_numbers) def _(event): " When the pane numbers are shown. Any key press should hide them. " pymux.display_pane_numbers = False @Condition def clock_displayed(): " " pane = pymux.arrangement.get_active_pane() return pane.clock_mode @kb.add(Keys.Any, eager=True, filter=clock_displayed) def _(event): " When the clock is displayed. Any key press should hide it. " pane = pymux.arrangement.get_active_pane() pane.clock_mode = False return kb def add_custom_binding(self, key_name, command, arguments, needs_prefix=False): """ Add custom binding (for the "bind-key" command.) Raises ValueError if the give `key_name` is an invalid name. :param key_name: Pymux key name, for instance "C-a" or "M-x". """ assert isinstance(key_name, six.text_type) assert isinstance(command, six.text_type) assert isinstance(arguments, list) # Unbind previous key. self.remove_custom_binding(key_name, needs_prefix=needs_prefix) # Translate the pymux key name into a prompt_toolkit key sequence. # (Can raise ValueError.) keys_sequence = pymux_key_to_prompt_toolkit_key_sequence(key_name) # Create handler and add to Registry. if needs_prefix: filter = HasPrefix(self.pymux) else: filter = ~HasPrefix(self.pymux) filter = filter & ~(WaitsForConfirmation(self.pymux) | has_focus(COMMAND) | has_focus(PROMPT)) def key_handler(event): " The actual key handler. " call_command_handler(command, self.pymux, arguments) self.pymux.get_client_state().has_prefix = False self.custom_key_bindings.add(*keys_sequence, filter=filter)(key_handler) # Store key in `custom_bindings` in order to be able to call # "unbind-key" later on. k = (needs_prefix, key_name) self.custom_bindings[k] = CustomBinding(key_handler, command, arguments) def remove_custom_binding(self, key_name, needs_prefix=False): """ Remove custom key binding for a key. :param key_name: Pymux key name, for instance "C-A". """ k = (needs_prefix, key_name) if k in self.custom_bindings: self.custom_key_bindings.remove(self.custom_bindings[k].handler) del self.custom_bindings[k]