예제 #1
0
    def __init__(
        self,
        layout: Optional[Layout] = None,
        style: Optional[BaseStyle] = None,
        include_default_pygments_style: FilterOrBool = True,
        style_transformation: Optional[StyleTransformation] = None,
        key_bindings: Optional[KeyBindingsBase] = None,
        clipboard: Optional[Clipboard] = None,
        full_screen: bool = False,
        color_depth: Union[ColorDepth, Callable[[], Union[ColorDepth, None]],
                           None] = None,
        mouse_support: FilterOrBool = False,
        enable_page_navigation_bindings: Optional[
            FilterOrBool] = None,  # Can be None, True or False.
        paste_mode: FilterOrBool = False,
        editing_mode: EditingMode = EditingMode.EMACS,
        erase_when_done: bool = False,
        reverse_vi_search_direction: FilterOrBool = False,
        min_redraw_interval: Union[float, int, None] = None,
        max_render_postpone_time: Union[float, int, None] = 0.01,
        refresh_interval: Optional[float] = None,
        on_reset: Optional[ApplicationEventHandler] = None,
        on_invalidate: Optional[ApplicationEventHandler] = None,
        before_render: Optional[ApplicationEventHandler] = None,
        after_render: Optional[ApplicationEventHandler] = None,
        # I/O.
        input: Optional[Input] = None,
        output: Optional[Output] = None,
    ):

        # If `enable_page_navigation_bindings` is not specified, enable it in
        # case of full screen applications only. This can be overridden by the user.
        if enable_page_navigation_bindings is None:
            enable_page_navigation_bindings = Condition(
                lambda: self.full_screen)

        paste_mode = to_filter(paste_mode)
        mouse_support = to_filter(mouse_support)
        reverse_vi_search_direction = to_filter(reverse_vi_search_direction)
        enable_page_navigation_bindings = to_filter(
            enable_page_navigation_bindings)
        include_default_pygments_style = to_filter(
            include_default_pygments_style)

        if layout is None:
            layout = create_dummy_layout()

        if style_transformation is None:
            style_transformation = DummyStyleTransformation()

        self.style = style
        self.style_transformation = style_transformation

        # Key bindings.
        self.key_bindings = key_bindings
        self._default_bindings = load_key_bindings()
        self._page_navigation_bindings = load_page_navigation_bindings()

        self.layout = layout
        self.clipboard = clipboard or InMemoryClipboard()
        self.full_screen: bool = full_screen
        self._color_depth = color_depth
        self.mouse_support = mouse_support

        self.paste_mode = paste_mode
        self.editing_mode = editing_mode
        self.erase_when_done = erase_when_done
        self.reverse_vi_search_direction = reverse_vi_search_direction
        self.enable_page_navigation_bindings = enable_page_navigation_bindings
        self.min_redraw_interval = min_redraw_interval
        self.max_render_postpone_time = max_render_postpone_time
        self.refresh_interval = refresh_interval

        # Events.
        self.on_invalidate = Event(self, on_invalidate)
        self.on_reset = Event(self, on_reset)
        self.before_render = Event(self, before_render)
        self.after_render = Event(self, after_render)

        # I/O.
        session = get_app_session()
        self.output = output or session.output
        self.input = input or session.input

        # List of 'extra' functions to execute before a Application.run.
        self.pre_run_callables: List[Callable[[], None]] = []

        self._is_running = False
        self.future: Optional[Future[_AppResult]] = None
        self.loop: Optional[AbstractEventLoop] = None
        self.context: Optional[contextvars.Context] = None

        #: Quoted insert. This flag is set if we go into quoted insert mode.
        self.quoted_insert = False

        #: Vi state. (For Vi key bindings.)
        self.vi_state = ViState()
        self.emacs_state = EmacsState()

        #: When to flush the input (For flushing escape keys.) This is important
        #: on terminals that use vt100 input. We can't distinguish the escape
        #: key from for instance the left-arrow key, if we don't know what follows
        #: after "\x1b". This little timer will consider "\x1b" to be escape if
        #: nothing did follow in this time span.
        #: This seems to work like the `ttimeoutlen` option in Vim.
        self.ttimeoutlen = 0.5  # Seconds.

        #: Like Vim's `timeoutlen` option. This can be `None` or a float.  For
        #: instance, suppose that we have a key binding AB and a second key
        #: binding A. If the uses presses A and then waits, we don't handle
        #: this binding yet (unless it was marked 'eager'), because we don't
        #: know what will follow. This timeout is the maximum amount of time
        #: that we wait until we call the handlers anyway. Pass `None` to
        #: disable this timeout.
        self.timeoutlen = 1.0

        #: The `Renderer` instance.
        # Make sure that the same stdout is used, when a custom renderer has been passed.
        self._merged_style = self._create_merged_style(
            include_default_pygments_style)

        self.renderer = Renderer(
            self._merged_style,
            self.output,
            full_screen=full_screen,
            mouse_support=mouse_support,
            cpr_not_supported_callback=self.cpr_not_supported_callback,
        )

        #: Render counter. This one is increased every time the UI is rendered.
        #: It can be used as a key for caching certain information during one
        #: rendering.
        self.render_counter = 0

        # Invalidate flag. When 'True', a repaint has been scheduled.
        self._invalidated = False
        self._invalidate_events: List[Event[object]] = [
        ]  # Collection of 'invalidate' Event objects.
        self._last_redraw_time = 0.0  # Unix timestamp of last redraw. Used when
        # `min_redraw_interval` is given.

        #: The `InputProcessor` instance.
        self.key_processor = KeyProcessor(_CombinedRegistry(self))

        # If `run_in_terminal` was called. This will point to a `Future` what will be
        # set at the point when the previous run finishes.
        self._running_in_terminal = False
        self._running_in_terminal_f: Optional[Future[None]] = None

        # Trigger initialize callback.
        self.reset()
예제 #2
0
def test_emacs_yank():
    # ControlY (yank)
    c = InMemoryClipboard(ClipboardData('XYZ'))
    result, cli = _feed_cli_with_input('hello\x02\x19\n', clipboard=c)
    assert result.text == 'hellXYZo'
    assert result.cursor_position == len('hellXY')
예제 #3
0
    def __init__(self,
                 message='',
                 default='',
                 multiline=False,
                 wrap_lines=True,
                 is_password=False,
                 vi_mode=False,
                 editing_mode=EditingMode.EMACS,
                 complete_while_typing=True,
                 validate_while_typing=True,
                 enable_history_search=False,
                 search_ignore_case=False,
                 lexer=None,
                 enable_system_prompt=False,
                 enable_suspend=False,
                 enable_open_in_editor=False,
                 validator=None,
                 completer=None,
                 complete_in_thread=False,
                 reserve_space_for_menu=8,
                 complete_style=None,
                 auto_suggest=None,
                 style=None,
                 color_depth=None,
                 include_default_pygments_style=True,
                 history=None,
                 clipboard=None,
                 prompt_continuation=None,
                 rprompt=None,
                 bottom_toolbar=None,
                 mouse_support=False,
                 input_processors=None,
                 key_bindings=None,
                 erase_when_done=False,
                 tempfile_suffix='.txt',
                 inputhook=None,
                 refresh_interval=0,
                 input=None,
                 output=None):
        assert style is None or isinstance(style, BaseStyle)
        assert input_processors is None or isinstance(input_processors, list)
        assert key_bindings is None or isinstance(key_bindings,
                                                  KeyBindingsBase)

        # Defaults.
        output = output or get_default_output()
        input = input or get_default_input()

        history = history or InMemoryHistory()
        clipboard = clipboard or InMemoryClipboard()

        # Ensure backwards-compatibility, when `vi_mode` is passed.
        if vi_mode:
            editing_mode = EditingMode.VI

        # Store all settings in this class.
        self.input = input
        self.output = output

        # Store all settings in this class.
        for name in self._fields:
            if name not in ('editing_mode', ):
                value = locals()[name]
                setattr(self, name, value)

        # Create buffers, layout and Application.
        self.history = history
        self.default_buffer = self._create_default_buffer()
        self.search_buffer = self._create_search_buffer()
        self.layout = self._create_layout()
        self.app = self._create_application(editing_mode, erase_when_done)
예제 #4
0
def test_emacs_yank():
    # ControlY (yank)
    c = InMemoryClipboard(ClipboardData("XYZ"))
    result, cli = _feed_cli_with_input("hello\x02\x19\r", clipboard=c)
    assert result.text == "hellXYZo"
    assert result.cursor_position == len("hellXYZ")
예제 #5
0
    def __init__(self,
                 message: AnyFormattedText = '',
                 multiline: FilterOrBool = False,
                 wrap_lines: FilterOrBool = True,
                 is_password: FilterOrBool = False,
                 vi_mode: bool = False,
                 editing_mode: EditingMode = EditingMode.EMACS,
                 complete_while_typing: FilterOrBool = True,
                 validate_while_typing: FilterOrBool = True,
                 enable_history_search: FilterOrBool = False,
                 search_ignore_case: FilterOrBool = False,
                 lexer: Optional[Lexer] = None,
                 enable_system_prompt: FilterOrBool = False,
                 enable_suspend: FilterOrBool = False,
                 enable_open_in_editor: FilterOrBool = False,
                 validator: Optional[Validator] = None,
                 completer: Optional[Completer] = None,
                 complete_in_thread: bool = False,
                 reserve_space_for_menu: int = 8,
                 complete_style: CompleteStyle = CompleteStyle.COLUMN,
                 auto_suggest: Optional[AutoSuggest] = None,
                 style: Optional[BaseStyle] = None,
                 style_transformation: Optional[StyleTransformation] = None,
                 swap_light_and_dark_colors: FilterOrBool = False,
                 color_depth: Optional[ColorDepth] = None,
                 include_default_pygments_style: FilterOrBool = True,
                 history: Optional[History] = None,
                 clipboard: Optional[Clipboard] = None,
                 prompt_continuation: PromptContinuationText = '',
                 rprompt: AnyFormattedText = None,
                 bottom_toolbar: AnyFormattedText = None,
                 mouse_support: FilterOrBool = False,
                 input_processors: Optional[List[Processor]] = None,
                 key_bindings: Optional[KeyBindingsBase] = None,
                 erase_when_done: bool = False,
                 tempfile_suffix: str = '.txt',
                 refresh_interval: float = 0,
                 input: Optional[Input] = None,
                 output: Optional[Output] = None) -> None:

        history = history or InMemoryHistory()
        clipboard = clipboard or InMemoryClipboard()

        # Ensure backwards-compatibility, when `vi_mode` is passed.
        if vi_mode:
            editing_mode = EditingMode.VI

        # Store all settings in this class.
        self.input = input
        self.output = output

        # Store all settings in this class.

        # Store attributes.
        # (All except 'editing_mode'.)
        self.message = message
        self.lexer = lexer
        self.completer = completer
        self.complete_in_thread = complete_in_thread
        self.is_password = is_password
        self.key_bindings = key_bindings
        self.bottom_toolbar = bottom_toolbar
        self.style = style
        self.style_transformation = style_transformation
        self.swap_light_and_dark_colors = swap_light_and_dark_colors
        self.color_depth = color_depth
        self.include_default_pygments_style = include_default_pygments_style
        self.rprompt = rprompt
        self.multiline = multiline
        self.prompt_continuation = prompt_continuation
        self.wrap_lines = wrap_lines
        self.enable_history_search = enable_history_search
        self.search_ignore_case = search_ignore_case
        self.complete_while_typing = complete_while_typing
        self.validate_while_typing = validate_while_typing
        self.complete_style = complete_style
        self.mouse_support = mouse_support
        self.auto_suggest = auto_suggest
        self.clipboard = clipboard
        self.validator = validator
        self.refresh_interval = refresh_interval
        self.input_processors = input_processors
        self.enable_system_prompt = enable_system_prompt
        self.enable_suspend = enable_suspend
        self.enable_open_in_editor = enable_open_in_editor
        self.reserve_space_for_menu = reserve_space_for_menu
        self.tempfile_suffix = tempfile_suffix

        # Create buffers, layout and Application.
        self.history = history
        self.default_buffer = self._create_default_buffer()
        self.search_buffer = self._create_search_buffer()
        self.layout = self._create_layout()
        self.app = self._create_application(editing_mode, erase_when_done)
예제 #6
0
    def __init__(
            self,
            layout=None,
            style=None,
            include_default_pygments_style=True,
            key_bindings=None,
            clipboard=None,
            full_screen=False,
            mouse_support=False,
            enable_page_navigation_bindings=None,  # Can be None, True or False.
            paste_mode=False,
            editing_mode=EditingMode.EMACS,
            erase_when_done=False,
            reverse_vi_search_direction=False,
            min_redraw_interval=None,
            max_render_postpone_time=0,
            on_reset=None,
            on_invalidate=None,
            before_render=None,
            after_render=None,

            # I/O.
            input=None,
            output=None):

        # If `enable_page_navigation_bindings` is not specified, enable it in
        # case of full screen applications only. This can be overridden by the user.
        if enable_page_navigation_bindings is None:
            enable_page_navigation_bindings = Condition(
                lambda: self.full_screen)

        paste_mode = to_filter(paste_mode)
        mouse_support = to_filter(mouse_support)
        reverse_vi_search_direction = to_filter(reverse_vi_search_direction)
        enable_page_navigation_bindings = to_filter(
            enable_page_navigation_bindings)
        include_default_pygments_style = to_filter(
            include_default_pygments_style)

        assert layout is None or isinstance(
            layout, Layout), 'Got layout: %r' % (layout, )
        assert key_bindings is None or isinstance(key_bindings,
                                                  KeyBindingsBase)
        assert clipboard is None or isinstance(clipboard, Clipboard)
        assert isinstance(full_screen, bool)
        assert isinstance(editing_mode, six.string_types)
        assert style is None or isinstance(style, BaseStyle)
        assert isinstance(erase_when_done, bool)
        assert min_redraw_interval is None or isinstance(
            min_redraw_interval, (float, int))
        assert max_render_postpone_time is None or isinstance(
            max_render_postpone_time, (float, int))

        assert on_reset is None or callable(on_reset)
        assert on_invalidate is None or callable(on_invalidate)
        assert before_render is None or callable(before_render)
        assert after_render is None or callable(after_render)

        assert output is None or isinstance(output, Output)
        assert input is None or isinstance(input, Input)

        self.style = style

        if layout is None:
            layout = create_dummy_layout()

        # Key bindings.
        self.key_bindings = key_bindings
        self._default_bindings = load_key_bindings()
        self._page_navigation_bindings = load_page_navigation_bindings()

        self.layout = layout
        self.clipboard = clipboard or InMemoryClipboard()
        self.full_screen = full_screen
        self.mouse_support = mouse_support

        self.paste_mode = paste_mode
        self.editing_mode = editing_mode
        self.erase_when_done = erase_when_done
        self.reverse_vi_search_direction = reverse_vi_search_direction
        self.enable_page_navigation_bindings = enable_page_navigation_bindings
        self.min_redraw_interval = min_redraw_interval
        self.max_render_postpone_time = max_render_postpone_time

        # Events.
        self.on_invalidate = Event(self, on_invalidate)
        self.on_reset = Event(self, on_reset)
        self.before_render = Event(self, before_render)
        self.after_render = Event(self, after_render)

        # I/O.
        self.output = output or get_default_output()
        self.input = input or get_default_input()

        # List of 'extra' functions to execute before a Application.run.
        self.pre_run_callables = []

        self._is_running = False
        self.future = None

        #: Quoted insert. This flag is set if we go into quoted insert mode.
        self.quoted_insert = False

        #: Vi state. (For Vi key bindings.)
        self.vi_state = ViState()

        #: When to flush the input (For flushing escape keys.) This is important
        #: on terminals that use vt100 input. We can't distinguish the escape
        #: key from for instance the left-arrow key, if we don't know what follows
        #: after "\x1b". This little timer will consider "\x1b" to be escape if
        #: nothing did follow in this time span.
        #: This seems to work like the `ttimeoutlen` option in Vim.
        self.input_timeout = .5

        #: The `Renderer` instance.
        # Make sure that the same stdout is used, when a custom renderer has been passed.
        self._merged_style = self._create_merged_style(
            include_default_pygments_style)

        self.renderer = Renderer(
            self._merged_style,
            self.output,
            full_screen=full_screen,
            mouse_support=mouse_support,
            cpr_not_supported_callback=self.cpr_not_supported_callback)

        #: Render counter. This one is increased every time the UI is rendered.
        #: It can be used as a key for caching certain information during one
        #: rendering.
        self.render_counter = 0

        # Invalidate flag. When 'True', a repaint has been scheduled.
        self._invalidated = False
        self._invalidate_events = [
        ]  # Collection of 'invalidate' Event objects.
        self._last_redraw_time = 0  # Unix timestamp of last redraw. Used when
        # `min_redraw_interval` is given.

        #: The `InputProcessor` instance.
        self.key_processor = KeyProcessor(_CombinedRegistry(self))

        # If `run_in_terminal` was called. This will point to a `Future` what will be
        # set at the point when the previous run finishes.
        self._running_in_terminal = False
        self._running_in_terminal_f = None

        # Trigger initialize callback.
        self.reset()