def choose_version(assets): '''choose a version from assets list''' versions = list(map(lambda item: item['version'], assets)) # print(versions) values = list(map(lambda item: (item, item), versions)) rdo = NewRadioList(values) def do_exit(event): # get_app().exit() event.app.exit(result=rdo.current_value) def do_up_down(event): print(event) pass bindings = KeyBindings() bindings.add('enter')(do_exit) app_bindings = merge_key_bindings([load_key_bindings(), bindings]) selected = Application(layout=Layout(rdo), key_bindings=app_bindings).run() if selected in versions: print('your choice is:', end=' ') # refer: https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/examples/print-text/ansi.py print_formatted_text(ANSI('\x1b[91m{0}'.format(selected))) return selected else: print('canceled')
def test_prefix_meta(): # Test the prefix-meta command. b = KeyBindings() b.add('j', 'j', filter=ViInsertMode())(prefix_meta) result, cli = _feed_cli_with_input( 'hellojjIX\r', key_bindings=b, editing_mode=EditingMode.VI) assert result.text == 'Xhello'
def test_prefix_meta(): # Test the prefix-meta command. b = KeyBindings() b.add('j', 'j', filter=ViInsertMode())(prefix_meta) result, cli = _feed_cli_with_input( 'hellojjIX\r', key_bindings=b, editing_mode=EditingMode.VI) assert result.text == 'Xhello'
def __init__(self, body: AnyContainer, title: AnyFormattedText = '', buttons: Optional[Sequence[Button]] = None, modal: bool = True, width: AnyDimension = None, with_background: bool = False) -> None: self.body = body self.title = title buttons = buttons or [] # When a button is selected, handle left/right key bindings. buttons_kb = KeyBindings() if len(buttons) > 1: first_selected = has_focus(buttons[0]) last_selected = has_focus(buttons[-1]) buttons_kb.add('left', filter=~first_selected)(focus_previous) buttons_kb.add('right', filter=~last_selected)(focus_next) frame_body: AnyContainer if buttons: frame_body = HSplit([ # Add optional padding around the body. Box(body=DynamicContainer(lambda: self.body), padding=D(preferred=1, max=1), padding_bottom=0), # The buttons. Box(body=VSplit(buttons, padding=1, key_bindings=buttons_kb), height=D(min=1, max=3, preferred=3)) ]) else: frame_body = body # Key bindings for whole dialog. kb = KeyBindings() kb.add('tab', filter=~has_completions)(focus_next) kb.add('s-tab', filter=~has_completions)(focus_previous) frame = Shadow(body=Frame( title=lambda: self.title, body=frame_body, style='class:dialog.body', width=(None if with_background is None else width), key_bindings=kb, modal=modal, )) self.container: Union[Box, Shadow] if with_background: self.container = Box( body=frame, style='class:dialog', width=width) else: self.container = frame
def _build_key_bindings(self): focussed = has_focus(self.system_buffer) # Emacs emacs_bindings = KeyBindings() handle = emacs_bindings.add @handle('escape', filter=focussed) @handle('c-g', filter=focussed) @handle('c-c', filter=focussed) def _(event): " Hide system prompt. " self.system_buffer.reset() event.app.layout.focus_previous() @handle('enter', filter=focussed) def _(event): " Run system command. " event.app.run_system_command( self.system_buffer.text, display_before_text=self._get_display_before_text()) self.system_buffer.reset(append_to_history=True) event.app.layout.focus_previous() # Vi. vi_bindings = KeyBindings() handle = vi_bindings.add @handle('escape', filter=focussed) @handle('c-c', filter=focussed) def _(event): " Hide system prompt. " event.app.vi_state.input_mode = InputMode.NAVIGATION self.system_buffer.reset() event.app.layout.focus_previous() @handle('enter', filter=focussed) def _(event): " Run system command. " event.app.vi_state.input_mode = InputMode.NAVIGATION event.app.run_system_command( self.system_buffer.text, display_before_text=self._get_display_before_text()) self.system_buffer.reset(append_to_history=True) event.app.layout.focus_previous() return merge_key_bindings([ ConditionalKeyBindings(emacs_bindings, emacs_mode), ConditionalKeyBindings(vi_bindings, vi_mode), ])
def _create_app(dialog: AnyContainer, style: Optional[BaseStyle]) -> Application[Any]: # Key bindings. bindings = KeyBindings() bindings.add('tab')(focus_next) bindings.add('s-tab')(focus_previous) return Application( layout=Layout(dialog), key_bindings=merge_key_bindings([ load_key_bindings(), bindings, ]), mouse_support=True, style=style, full_screen=True)
def _create_app(dialog, style): # Key bindings. bindings = KeyBindings() bindings.add('tab')(focus_next) bindings.add('s-tab')(focus_previous) return Application( layout=Layout(dialog), key_bindings=merge_key_bindings([ load_key_bindings(), bindings, ]), mouse_support=True, style=style, full_screen=True)
def _create_app(dialog: AnyContainer, style: Optional[BaseStyle]) -> Application[Any]: # Key bindings. bindings = KeyBindings() bindings.add("tab")(focus_next) bindings.add("s-tab")(focus_previous) bindings.add("down")(focus_next) bindings.add("up")(focus_previous) return Application( layout=Layout(dialog), key_bindings=merge_key_bindings([load_key_bindings(), bindings]), mouse_support=True, style=style, full_screen=True, )
def create_key_bindings(): kb = KeyBindings() handle = kb.add # emit completion @handle('c-j', filter=insert_mode & default_focussed & app.completion_is_selected) @handle('enter', filter=insert_mode & default_focussed & app.completion_is_selected) def _(event): event.current_buffer.complete_state = None # cancel completion @handle('c-c', filter=default_focussed & app.has_completions) def _(event): event.current_buffer.cancel_completion() # new line @handle('escape', 'enter', filter=emacs_insert_mode) def _(event): if event.current_buffer.text: copy_margin = not in_paste_mode( ) and event.app.session.auto_indentation event.current_buffer.newline(copy_margin=copy_margin) return kb
def __init__(self, show_message, **kwargs): self.show_message = show_message super().__init__(**kwargs) key_bindings = KeyBindings() handle = key_bindings.add # Readline-style bindings. handle("home")(get_by_name("beginning-of-line")) handle("end")(get_by_name("end-of-line")) handle("left")(get_by_name("backward-char")) handle("right")(get_by_name("forward-char")) @handle("up") def _(event: KeyPressEvent) -> None: event.current_buffer.auto_up(count=event.arg) @handle("down") def _(event: KeyPressEvent) -> None: event.current_buffer.auto_down(count=event.arg) self._default_bindings = merge_key_bindings( [ key_bindings, load_emacs_shift_selection_bindings() ])
def _create_more_prompt(message='--MORE--'): """ Create a `Prompt` object for displaying the "--MORE--". """ from prompt_toolkit.shortcuts import Prompt bindings = KeyBindings() @bindings.add(' ') @bindings.add('y') @bindings.add('Y') @bindings.add(Keys.ControlJ) @bindings.add(Keys.ControlM) @bindings.add(Keys.ControlI) # Tab. def _(event): event.app.set_return_value(True) @bindings.add('n') @bindings.add('N') @bindings.add('q') @bindings.add('Q') @bindings.add(Keys.ControlC) def _(event): event.app.set_return_value(False) @bindings.add(Keys.Any) def _(event): " Disable inserting of text. " prompt = Prompt(message, extra_key_bindings=bindings, erase_when_done=True) return prompt
def _create_interruption_dialog() -> PromptSession[InterruptAction]: bindings = KeyBindings() @bindings.add(Keys.Enter) @bindings.add(Keys.Escape) def nothing(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.NOTHING) @bindings.add("c-c") @bindings.add("C") @bindings.add("c") def kill(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.KILL) @bindings.add("c-d") @bindings.add("D") @bindings.add("d") def detach(event: KeyPressEvent) -> None: event.app.exit(result=InterruptAction.DETACH) @bindings.add(Keys.Any) def _(event: KeyPressEvent) -> None: # Disallow inserting other text. pass message = HTML(" <b>Interrupted</b>. Please choose the action:\n") suffix = HTML("<b>Ctrl-C</b> or <b>C</b> -- Kill\n" "<b>Ctrl-D</b> or <b>D</b> -- Detach \n" "<b>Enter</b> or <b>ESC</b> -- Continue the attached mode") complete_message = merge_formatted_text([message, suffix]) session: PromptSession[InterruptAction] = PromptSession( complete_message, key_bindings=bindings) return session
def create_confirm_prompt(message): """ Create a `Prompt` object for the 'confirm' function. """ assert isinstance(message, text_type) bindings = KeyBindings() @bindings.add('y') @bindings.add('Y') def yes(event): prompt.default_buffer.text = 'y' event.app.set_result(True) @bindings.add('n') @bindings.add('N') @bindings.add('c-c') def no(event): prompt.default_buffer.text = 'n' event.app.set_result(False) @bindings.add(Keys.Any) def _(event): " Disallow inserting other text. " pass prompt = Prompt(message, extra_key_bindings=bindings) return prompt
def _create_prompt_bindings(self): """ Create the KeyBindings for a prompt application. """ kb = KeyBindings() handle = kb.add default_focused = has_focus(DEFAULT_BUFFER) @Condition def do_accept(): return (not _true(self.multiline) and self.app.layout.current_control == self._default_buffer_control) @handle('enter', filter=do_accept & default_focused) def _(event): " Accept input when enter has been pressed. " self.default_buffer.validate_and_handle() @Condition def readline_complete_style(): return self.complete_style == CompleteStyle.READLINE_LIKE @handle('tab', filter=readline_complete_style & default_focused) def _(event): " Display completions (like readline). " display_completions_like_readline(event) @handle('c-c', filter=default_focused) def _(event): " Abort when Control-C has been pressed. " event.app.abort() @Condition def ctrl_d_condition(): """ Ctrl-D binding is only active when the default buffer is selected and empty. """ app = get_app() return (app.current_buffer.name == DEFAULT_BUFFER and not app.current_buffer.text) @handle('c-d', filter=ctrl_d_condition & default_focused) def _(event): " Exit when Control-D has been pressed. " event.app.exit() suspend_supported = Condition(suspend_to_background_supported) @Condition def enable_suspend(): return to_filter(self.enable_suspend)() @handle('c-z', filter=suspend_supported & enable_suspend) def _(event): """ Suspend process to background. """ event.app.suspend_to_background() return kb
def create_confirm_session(message, suffix=' (y/n) '): """ Create a `PromptSession` object for the 'confirm' function. """ assert isinstance(message, text_type) bindings = KeyBindings() @bindings.add('y') @bindings.add('Y') def yes(event): session.default_buffer.text = 'y' event.app.exit(result=True) @bindings.add('n') @bindings.add('N') @bindings.add('c-c') def no(event): session.default_buffer.text = 'n' event.app.exit(result=False) @bindings.add(Keys.Any) def _(event): " Disallow inserting other text. " pass complete_message = merge_formatted_text([message, suffix]) session = PromptSession(complete_message, key_bindings=bindings) return session
def load_auto_suggest_bindings(): """ Key bindings for accepting auto suggestion text. (This has to come after the Vi bindings, because they also have an implementation for the "right arrow", but we really want the suggestion binding when a suggestion is available.) """ key_bindings = KeyBindings() handle = key_bindings.add @Condition def suggestion_available(): app = get_app() return (app.current_buffer.suggestion is not None and app.current_buffer.document.is_cursor_at_the_end) @handle('c-f', filter=suggestion_available) @handle('c-e', filter=suggestion_available) @handle('right', filter=suggestion_available) def _(event): " Accept suggestion. " b = event.current_buffer suggestion = b.suggestion if suggestion: b.insert_text(suggestion.text) return key_bindings
def _create_more_session(message: str = '--MORE--') -> 'PromptSession': """ Create a `PromptSession` object for displaying the "--MORE--". """ from prompt_toolkit.shortcuts import PromptSession bindings = KeyBindings() @bindings.add(' ') @bindings.add('y') @bindings.add('Y') @bindings.add(Keys.ControlJ) @bindings.add(Keys.ControlM) @bindings.add(Keys.ControlI) # Tab. def _(event: E) -> None: event.app.exit(result=True) @bindings.add('n') @bindings.add('N') @bindings.add('q') @bindings.add('Q') @bindings.add(Keys.ControlC) def _(event: E) -> None: event.app.exit(result=False) @bindings.add(Keys.Any) def _(event: E) -> None: " Disable inserting of text. " return PromptSession(message, key_bindings=bindings, erase_when_done=True)
def _create_more_session(message: str = "--MORE--") -> "PromptSession": """ Create a `PromptSession` object for displaying the "--MORE--". """ from prompt_toolkit.shortcuts import PromptSession bindings = KeyBindings() @bindings.add(" ") @bindings.add("y") @bindings.add("Y") @bindings.add(Keys.ControlJ) @bindings.add(Keys.ControlM) @bindings.add(Keys.ControlI) # Tab. def _yes(event: E) -> None: event.app.exit(result=True) @bindings.add("n") @bindings.add("N") @bindings.add("q") @bindings.add("Q") @bindings.add(Keys.ControlC) def _no(event: E) -> None: event.app.exit(result=False) @bindings.add(Keys.Any) def _ignore(event: E) -> None: " Disable inserting of text. " return PromptSession(message, key_bindings=bindings, erase_when_done=True)
def __init__(self, values: Sequence[Tuple[_T, AnyFormattedText]]) -> None: assert len(values) > 0 self.values = values # current_values will be used in multiple_selection, # current_value will be used otherwise. self.current_values: List[_T] = [] self.current_value: _T = values[0][0] self._selected_index = 0 # Key bindings. kb = KeyBindings() @kb.add("up") def _(event: E) -> None: self._selected_index = max(0, self._selected_index - 1) @kb.add("down") def _(event: E) -> None: self._selected_index = min(len(self.values) - 1, self._selected_index + 1) @kb.add("pageup") def _(event: E) -> None: w = event.app.layout.current_window self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines) ) @kb.add("pagedown") def _(event: E) -> None: w = event.app.layout.current_window self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines), ) @kb.add("enter") @kb.add(" ") def _(event: E) -> None: self._handle_enter() @kb.add(Keys.Any) def _(event: E) -> None: # We first check values after the selected value, then all values. for value in self.values[self._selected_index + 1 :] + self.values: if value[1].startswith(event.data): self._selected_index = self.values.index(value) return # 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=[ScrollbarMargin(display_arrows=True),], dont_extend_height=True, )
def bindings(handlers): bindings = KeyBindings() bindings.add(Keys.ControlX, Keys.ControlC)(handlers.controlx_controlc) bindings.add(Keys.ControlX)(handlers.control_x) bindings.add(Keys.ControlD)(handlers.control_d) bindings.add(Keys.ControlSquareClose, Keys.Any)(handlers.control_square_close_any) return bindings
def create_key_bindings(editor=""): kb = KeyBindings() handle = kb.add # emit completion @handle('c-j', filter=insert_mode & default_focused & completion_is_selected) @handle('enter', filter=insert_mode & default_focused & completion_is_selected) def _(event): event.current_buffer.complete_state = None # cancel completion @handle('c-c', filter=default_focused & has_completions) def _(event): event.current_buffer.cancel_completion() # new line @handle('escape', 'enter', filter=emacs_insert_mode) def _(event): if event.current_buffer.text: copy_margin = not in_paste_mode() and settings.auto_indentation event.current_buffer.newline(copy_margin=copy_margin) @handle('c-x', 'c-e', filter=emacs_mode & ~has_selection) def _(event): # match R behavior editor = roption("editor") if not editor or not isinstance(editor, text_type): if 'VISUAL' in os.environ: editor = os.environ['VISUAL'] elif 'EDITOR' in os.environ: editor = os.environ['EDITOR'] if not editor: editor = "vi" buff = event.current_buffer if editor: orig_visual = os.environ[ 'VISUAL'] if 'VISUAL' in os.environ else None os.environ['VISUAL'] = editor buff.open_in_editor() if editor: def run(): def cleanup(): if orig_visual: os.environ['VISUAL'] = orig_visual else: del os.environ['VISUAL'] yield From(run_in_terminal(cleanup, in_executor=True)) ensure_future(run()) return kb
def __init__(self, values): assert isinstance(values, list) assert len(values) > 0 assert all(isinstance(i, tuple) and len(i) == 2 for i in values) self.values = values self.current_value = values[0][0] self._selected_index = 0 # Key bindings. kb = KeyBindings() @kb.add('up') def _(event): self._selected_index = max(0, self._selected_index - 1) @kb.add('down') def _(event): self._selected_index = min( len(self.values) - 1, self._selected_index + 1) @kb.add('pageup') def _(event): w = event.app.layout.current_window self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines)) @kb.add('pagedown') def _(event): w = event.app.layout.current_window self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines)) @kb.add('enter') @kb.add(' ') def _(event): self.current_value = self.values[self._selected_index][0] @kb.add(Keys.Any) def _(event): # We first check values after the selected value, then all values. for value in self.values[self._selected_index + 1:] + self.values: if value[1].startswith(event.data): self._selected_index = self.values.index(value) return # Control and window. self.control = FormattedTextControl(self._get_text_fragments, key_bindings=kb, focusable=True) self.window = Window(content=self.control, style='class:radio-list', right_margins=[ ScrollbarMargin(display_arrows=True), ], dont_extend_height=True)
def _get_key_bindings(self): kb = KeyBindings() @kb.add(' ') @kb.add('enter') def _(event): if self.handler is not None: self.handler() return kb
def test_previous_key_sequence(processor): """ test whether we receive the correct previous_key_sequence. """ with set_dummy_app(): events = [] def handler(event): events.append(event) # Build registry. registry = KeyBindings() registry.add('a', 'a')(handler) registry.add('b', 'b')(handler) processor = KeyProcessor(registry) # Create processor and feed keys. processor.feed(KeyPress('a', 'a')) processor.feed(KeyPress('a', 'a')) processor.feed(KeyPress('b', 'b')) processor.feed(KeyPress('b', 'b')) processor.process_keys() # Test. assert len(events) == 2 assert len(events[0].key_sequence) == 2 assert events[0].key_sequence[0].key == 'a' assert events[0].key_sequence[0].data == 'a' assert events[0].key_sequence[1].key == 'a' assert events[0].key_sequence[1].data == 'a' assert events[0].previous_key_sequence == [] assert len(events[1].key_sequence) == 2 assert events[1].key_sequence[0].key == 'b' assert events[1].key_sequence[0].data == 'b' assert events[1].key_sequence[1].key == 'b' assert events[1].key_sequence[1].data == 'b' assert len(events[1].previous_key_sequence) == 2 assert events[1].previous_key_sequence[0].key == 'a' assert events[1].previous_key_sequence[0].data == 'a' assert events[1].previous_key_sequence[1].key == 'a' assert events[1].previous_key_sequence[1].data == 'a'
def _get_key_bindings(self) -> KeyBindings: " Key bindings for the Button. " kb = KeyBindings() @kb.add(' ') @kb.add('enter') def _(event: E) -> None: if self.handler is not None: self.handler() return kb
def _get_key_bindings(self) -> KeyBindings: " Key bindings for the Button. " kb = KeyBindings() @kb.add(" ") @kb.add("enter") def _(event: KeyPressEvent) -> None: if self.handler is not None: self.handler() return kb
def _get_kb(self): kb = KeyBindings() @kb.add('escape') def _(event): self.view.toolbar = Toolbar( self.view) # Hide "Find: " and fix focus: self.view.app.layout.focus((self.view.current_view or self.view.fileman).input_field) return kb
def test_previous_key_sequence(processor): """ test whether we receive the correct previous_key_sequence. """ with set_dummy_app(): events = [] def handler(event): events.append(event) # Build registry. registry = KeyBindings() registry.add('a', 'a')(handler) registry.add('b', 'b')(handler) processor = KeyProcessor(registry) # Create processor and feed keys. processor.feed(KeyPress('a', 'a')) processor.feed(KeyPress('a', 'a')) processor.feed(KeyPress('b', 'b')) processor.feed(KeyPress('b', 'b')) processor.process_keys() # Test. assert len(events) == 2 assert len(events[0].key_sequence) == 2 assert events[0].key_sequence[0].key == 'a' assert events[0].key_sequence[0].data == 'a' assert events[0].key_sequence[1].key == 'a' assert events[0].key_sequence[1].data == 'a' assert events[0].previous_key_sequence == [] assert len(events[1].key_sequence) == 2 assert events[1].key_sequence[0].key == 'b' assert events[1].key_sequence[0].data == 'b' assert events[1].key_sequence[1].key == 'b' assert events[1].key_sequence[1].data == 'b' assert len(events[1].previous_key_sequence) == 2 assert events[1].previous_key_sequence[0].key == 'a' assert events[1].previous_key_sequence[0].data == 'a' assert events[1].previous_key_sequence[1].key == 'a' assert events[1].previous_key_sequence[1].data == 'a'
def bindings(handlers): bindings = KeyBindings() bindings.add( Keys.ControlX, Keys.ControlC)(handlers.controlx_controlc) bindings.add(Keys.ControlX)(handlers.control_x) bindings.add(Keys.ControlD)(handlers.control_d) bindings.add( Keys.ControlSquareClose, Keys.Any)(handlers.control_square_close_any) return bindings
def _create_app(dialog, style): bindings = KeyBindings() bindings.add('tab')(focus_next) bindings.add('s-tab')(focus_previous) bindings.add('escape')(close) return Application(layout=Layout(dialog), key_bindings=merge_key_bindings([ load_key_bindings(), bindings, ]), mouse_support=True, style=style, full_screen=True)
def _confirm(question: str, default: bool = False, **kwargs) -> bool: bindings = KeyBindings() @bindings.add("y") @bindings.add("Y") def _yes(event: KeyPressEvent) -> None: session.default_buffer.text = "y" event.app.exit(result=True) @bindings.add("n") @bindings.add("N") def _no(event: KeyPressEvent) -> None: session.default_buffer.text = "n" event.app.exit(result=False) @bindings.add(Keys.Any) def _any(_: KeyPressEvent) -> None: # Disallow inserting other text. pass if default: default_indicator = "Y/n" bindings.add(Keys.Enter)(_yes) else: default_indicator = "y/N" bindings.add(Keys.Enter)(_no) complete_message = merge_formatted_text([question, f" ({default_indicator}): "]) session: shortcuts.PromptSession[bool] = shortcuts.PromptSession( complete_message, key_bindings=bindings, **kwargs ) return session.prompt(complete_message, key_bindings=bindings, **kwargs)
def _get_filemanager_kb(self, fm: Filemanager): kb_active = Condition(lambda: fm.view.fileman_visible) kb = KeyBindings() @kb.add('up') def _(event: E) -> None: self._selected_index = max(0, self._selected_index - 1) @kb.add('down') def _(event: E) -> None: self._selected_index = min( len(self.values) - 1, self._selected_index + 1) @kb.add('pageup') def _(event: E) -> None: w = event.app.layout.current_window self._selected_index = max( 0, self._selected_index - len(w.render_info.displayed_lines)) @kb.add('pagedown') def _(event: E) -> None: w = event.app.layout.current_window self._selected_index = min( len(self.values) - 1, self._selected_index + len(w.render_info.displayed_lines)) @kb.add('enter') def _(event: E) -> None: logging.debug("[FM] Selected: {}".format(self.selected)) if self.selected.endswith('/'): logging.debug("[FM] Changing dir: {}".format(self.selected)) self.fm.change_dir(Path(self.selected)) elif self.selected.endswith('|'): logging.debug("[FM] TODO handle: {}".format(self.selected)) pass # can't open PIPEs and other weird types else: logging.debug("[FM] Opening: {}".format(self.selected)) self._file_handler(self.selected) @kb.add('escape') def _(event: E) -> None: fm.view.app.layout.focus(fm.cancel_button) @kb.add('<any>') def _(event: E) -> None: # We first check values after the selected value, then all values. for value in self.values[self._selected_index + 1:] + self.values: if value.startswith(event.data): self._selected_index = self.values.index(value) return return ConditionalKeyBindings(kb, filter=kb_active)
def get_key_bindings(self): """ Expose key bindings that handle the left/right arrow keys when the menu is displayed. """ from prompt_toolkit.key_binding.key_bindings import KeyBindings kb = KeyBindings() @Condition def filter(): " Only handle key bindings if this menu is visible. " app = get_app() complete_state = app.current_buffer.complete_state # There need to be completions, and one needs to be selected. if complete_state is None or complete_state.complete_index is None: return False # This menu needs to be visible. return any( window.content == self for window in app.layout.visible_windows) def move(right=False): buff = get_app().current_buffer complete_state = buff.complete_state if complete_state is not None and \ buff.complete_state.complete_index is not None: # Calculate new complete index. new_index = buff.complete_state.complete_index if right: new_index += self._rendered_rows else: new_index -= self._rendered_rows if 0 <= new_index < len(complete_state.completions): buff.go_to_completion(new_index) # NOTE: the is_global is required because the completion menu will # never be focussed. @kb.add('left', is_global=True, filter=filter) def _(event): move() @kb.add('right', is_global=True, filter=filter) def _(event): move(True) return kb
def load_emacs_page_navigation_bindings() -> KeyBindingsBase: """ Key bindings, for scrolling up and down through pages. This are separate bindings, because GNU readline doesn't have them. """ key_bindings = KeyBindings() handle = key_bindings.add handle('c-v')(scroll_page_down) handle('pagedown')(scroll_page_down) handle('escape', 'v')(scroll_page_up) handle('pageup')(scroll_page_up) return ConditionalKeyBindings(key_bindings, emacs_mode)
def _create_search_mode_bindings(self): key_bindings = KeyBindings() handle = key_bindings.add default_focused = has_focus(DEFAULT_BUFFER) @handle('c-w', filter=default_focused) def _(event): buf = event.current_buffer self.completer.toggle_search_mode() buf.complete_state = None buf.start_completion() self.update_toolbar_text() return key_bindings
def conf_dialog(**kwargs): def row(label, default): buffer=Buffer() buffer.text = default return VSplit([ Label(HTML(f'{label}'), width=10), Window(width=2, char=": "), Window(content=BufferControl(buffer=buffer)), ]) help = Label(HTML(f'(Press {ansired("Tab][Down][Up")} to move cursor. {ansired("Ctrl+C][Esc")} to quit)')) rows = [row(k, v) for k, v in kwargs.items()] root_container = HSplit([ help, Window(height=1, char="-", width=10), *rows ]) kb = KeyBindings() @kb.add("c-c") @kb.add("escape") def _(event): event.app.exit() @kb.add('tab') @kb.add('down') def _(event): event.app.layout.focus_next() @kb.add("up") def _(event): event.app.layout.focus_previous() @kb.add("enter") def _(event): data = [] for child in root_container.children[2:]: value = child.children[-1].content.buffer.text data.append(value) return event.app.exit(data) layout = Layout(root_container) application = Application(layout=layout, full_screen=False, key_bindings=kb) return application.run()
def test_remove_bindings(handlers): with set_dummy_app(): h = handlers.controlx_controlc h2 = handlers.controld # Test passing a handler to the remove() function. bindings = KeyBindings() bindings.add(Keys.ControlX, Keys.ControlC)(h) bindings.add(Keys.ControlD)(h2) assert len(bindings.bindings) == 2 bindings.remove(h) assert len(bindings.bindings) == 1 # Test passing a key sequence to the remove() function. bindings = KeyBindings() bindings.add(Keys.ControlX, Keys.ControlC)(h) bindings.add(Keys.ControlD)(h2) assert len(bindings.bindings) == 2 bindings.remove(Keys.ControlX, Keys.ControlC) assert len(bindings.bindings) == 1