Exemple #1
0
def test_feed_simple(processor, handlers):
    with set_dummy_app():
        processor.feed(KeyPress(Keys.ControlX, '\x18'))
        processor.feed(KeyPress(Keys.ControlC, '\x03'))
        processor.process_keys()

        assert handlers.called == ['controlx_controlc']
Exemple #2
0
def test_control_square_closed_any(processor, handlers):
    with set_dummy_app():
        processor.feed(KeyPress(Keys.ControlSquareClose, ''))
        processor.feed(KeyPress('C', 'C'))
        processor.process_keys()

        assert handlers.called == ['control_square_close_any']
Exemple #3
0
def test_common_prefix(processor, handlers):
    with set_dummy_app():
        # Sending Control_X should not yet do anything, because there is
        # another sequence starting with that as well.
        processor.feed(KeyPress(Keys.ControlX, ''))
        processor.process_keys()

        assert handlers.called == []

        # When another key is pressed, we know that we did not meant the longer
        # "ControlX ControlC" sequence and the callbacks are called.
        processor.feed(KeyPress(Keys.ControlD, ''))
        processor.process_keys()

        assert handlers.called == ['control_x', 'control_d']
    def _merge_paired_surrogates(
            key_presses: List[KeyPress]) -> Iterator[KeyPress]:
        """
        Combines consecutive KeyPresses with high and low surrogates into
        single characters
        """
        buffered_high_surrogate = None
        for key in key_presses:
            is_text = not isinstance(key.key, Keys)
            is_high_surrogate = is_text and "\uD800" <= key.key <= "\uDBFF"
            is_low_surrogate = is_text and "\uDC00" <= key.key <= "\uDFFF"

            if buffered_high_surrogate:
                if is_low_surrogate:
                    # convert high surrogate + low surrogate to single character
                    fullchar = ((buffered_high_surrogate.key + key.key).encode(
                        "utf-16-le", "surrogatepass").decode("utf-16-le"))
                    key = KeyPress(fullchar, fullchar)
                else:
                    yield buffered_high_surrogate
                buffered_high_surrogate = None

            if is_high_surrogate:
                buffered_high_surrogate = key
            else:
                yield key

        if buffered_high_surrogate:
            yield buffered_high_surrogate
Exemple #5
0
 def _scroll_up(event: E) -> None:
     """
     Scroll up event without cursor position.
     """
     # We don't receive a cursor position, so we don't know which window to
     # scroll. Just send an 'up' key press instead.
     event.key_processor.feed(KeyPress(Keys.Up), first=True)
def simulate_key(menu, key):
    """ Simulate passing `key` to a menu """
    control = to_container(menu).content
    key_bindings = control.key_bindings
    key_processor = KeyProcessor(key_bindings)
    key_processor.feed(KeyPress(key))
    key_processor.process_keys()
Exemple #7
0
 def _newline2(event: E) -> None:
     r"""
     By default, handle \n as if it were a \r (enter).
     (It appears that some terminals send \n instead of \r when pressing
     enter. - at least the Linux subsystem for Windows.)
     """
     event.key_processor.feed(KeyPress(Keys.ControlM, "\r"), first=True)
    def read(self) -> Iterable[KeyPress]:
        """
        Return a list of `KeyPress` instances. It won't return anything when
        there was nothing to read.  (This function doesn't block.)

        http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx
        """
        max_count = 2048  # Max events to read at the same time.

        read = DWORD(0)
        arrtype = INPUT_RECORD * max_count
        input_records = arrtype()

        # Check whether there is some input to read. `ReadConsoleInputW` would
        # block otherwise.
        # (Actually, the event loop is responsible to make sure that this
        # function is only called when there is something to read, but for some
        # reason this happened in the asyncio_win32 loop, and it's better to be
        # safe anyway.)
        if not wait_for_handles([self.handle], timeout=0):
            return

        # Get next batch of input event.
        windll.kernel32.ReadConsoleInputW(self.handle, pointer(input_records),
                                          max_count, pointer(read))

        # First, get all the keys from the input buffer, in order to determine
        # whether we should consider this a paste event or not.
        all_keys = list(self._get_keys(read, input_records))

        # Fill in 'data' for key presses.
        all_keys = [self._insert_key_data(key) for key in all_keys]

        # Correct non-bmp characters that are passed as separate surrogate codes
        all_keys = list(self._merge_paired_surrogates(all_keys))

        if self.recognize_paste and self._is_paste(all_keys):
            gen = iter(all_keys)
            k: Optional[KeyPress]

            for k in gen:
                # Pasting: if the current key consists of text or \n, turn it
                # into a BracketedPaste.
                data = []
                while k and (not isinstance(k.key, Keys)
                             or k.key == Keys.ControlJ):
                    data.append(k.data)
                    try:
                        k = next(gen)
                    except StopIteration:
                        k = None

                if data:
                    yield KeyPress(Keys.BracketedPaste, "".join(data))
                if k is not None:
                    yield k
        else:
            for k2 in all_keys:
                yield k2
Exemple #9
0
    def _insert_key_data(self, key_press):
        """
        Insert KeyPress data, for vt100 compatibility.
        """
        if key_press.data:
            return key_press

        data = REVERSE_ANSI_SEQUENCES.get(key_press.key, '')
        return KeyPress(key_press.key, data)
Exemple #10
0
    def _handle_mouse(self, ev):
        """
        Handle mouse events. Return a list of KeyPress instances.
        """
        FROM_LEFT_1ST_BUTTON_PRESSED = 0x1
        FROM_LEFT_2ND_BUTTON_PRESSED = 0x2

        MOUSE_WHEEL_EFLAG = 0x4

        result = []

        # Check event type.
        if ev.ButtonState in [
                FROM_LEFT_1ST_BUTTON_PRESSED, FROM_LEFT_2ND_BUTTON_PRESSED
        ]:
            # On a key press, generate both the mouse down and up event.
            for event_type in [
                    MouseEventType.MOUSE_DOWN, MouseEventType.MOUSE_UP
            ]:
                try:
                    data = ";".join([
                        event_type.value,
                        str(ev.MousePosition.X),
                        str(ev.MousePosition.Y)
                    ] if not isinstance(event_type, str) else [
                        event_type,
                        str(ev.MousePosition.X),
                        str(ev.MousePosition.Y)
                    ])
                    result.append(KeyPress(Keys.WindowsMouseEvent, data))
                except Exception:
                    break
        # it's a scroll
        elif ev.EventFlags == MOUSE_WHEEL_EFLAG:
            # as described here:
            # https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
            # ButtonState is mouseData member
            if ev.ButtonState > 0:
                result.append(KeyPress(Keys.ScrollUp))
            if ev.ButtonState < 0:
                result.append(KeyPress(Keys.ScrollDown))

        return result
Exemple #11
0
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 prefix_meta(event):
    """
    Metafy the next character typed. This is for keyboards without a meta key.

    Sometimes people also want to bind other keys to Meta, e.g. 'jj'::

        key_bindings.add_key_binding('j', 'j', filter=ViInsertMode())(prefix_meta)
    """
    # ('first' should be true, because we want to insert it at the current
    # position in the queue.)
    event.app.key_processor.feed(KeyPress(Keys.Escape), first=True)
    def _insert_key_data(self, key_press: KeyPress) -> KeyPress:
        """
        Insert KeyPress data, for vt100 compatibility.
        """
        if key_press.data:
            return key_press

        if isinstance(key_press.key, Keys):
            data = REVERSE_ANSI_SEQUENCES.get(key_press.key, "")
        else:
            data = ""

        return KeyPress(key_press.key, data)
Exemple #14
0
    def _handle_mouse(self, ev: MOUSE_EVENT_RECORD) -> List[KeyPress]:
        """
        Handle mouse events. Return a list of KeyPress instances.
        """
        event_flags = ev.EventFlags
        button_state = ev.ButtonState

        event_type: Optional[MouseEventType] = None
        button: MouseButton = MouseButton.NONE

        # Scroll events.
        if event_flags & MOUSE_WHEELED:
            if button_state > 0:
                event_type = MouseEventType.SCROLL_UP
            else:
                event_type = MouseEventType.SCROLL_DOWN
        else:
            # Handle button state for non-scroll events.
            if button_state == FROM_LEFT_1ST_BUTTON_PRESSED:
                button = MouseButton.LEFT

            elif button_state == RIGHTMOST_BUTTON_PRESSED:
                button = MouseButton.RIGHT

        # Move events.
        if event_flags & MOUSE_MOVED:
            event_type = MouseEventType.MOUSE_MOVE

        # No key pressed anymore: mouse up.
        if event_type is None:
            if button_state > 0:
                # Some button pressed.
                event_type = MouseEventType.MOUSE_DOWN
            else:
                # No button pressed.
                event_type = MouseEventType.MOUSE_UP

        data = ";".join(
            [
                button.value,
                event_type.value,
                str(ev.MousePosition.X),
                str(ev.MousePosition.Y),
            ]
        )
        return [KeyPress(Keys.WindowsMouseEvent, data)]
    def _handle_mouse(self, ev):
        """
        Handle mouse events. Return a list of KeyPress instances.
        """
        FROM_LEFT_1ST_BUTTON_PRESSED = 0x1

        result = []

        # Check event type.
        if ev.ButtonState == FROM_LEFT_1ST_BUTTON_PRESSED:
            # On a key press, generate both the mouse down and up event.
            for event_type in [MouseEventType.MOUSE_DOWN, MouseEventType.MOUSE_UP]:
                data = ";".join(
                    [str(event_type), str(ev.MousePosition.X), str(ev.MousePosition.Y)]
                )
                result.append(KeyPress(Keys.WindowsMouseEvent, data))

        return result
    def _handle_mouse(self, ev: MOUSE_EVENT_RECORD) -> List[KeyPress]:
        """
        Handle mouse events. Return a list of KeyPress instances.
        """
        FROM_LEFT_1ST_BUTTON_PRESSED = 0x1
        MOUSE_MOVED = 0x0001
        MOUSE_WHEELED = 0x0004

        event_flags = ev.EventFlags
        button_state = ev.ButtonState

        result = []
        event_type: Optional[MouseEventType] = None

        # Move events.
        if event_flags & MOUSE_MOVED:
            if button_state == FROM_LEFT_1ST_BUTTON_PRESSED:
                event_type = MouseEventType.MOUSE_DOWN_MOVE

        # Scroll events.
        elif event_flags & MOUSE_WHEELED:
            if button_state > 0:
                event_type = MouseEventType.SCROLL_UP
            else:
                event_type = MouseEventType.SCROLL_DOWN

        # Mouse down (left button).
        elif button_state == FROM_LEFT_1ST_BUTTON_PRESSED:
            event_type = MouseEventType.MOUSE_DOWN

        # No key pressed anymore: mouse up.
        else:
            event_type = MouseEventType.MOUSE_UP

        if event_type is not None:
            data = ";".join([
                event_type.value,
                str(ev.MousePosition.X),
                str(ev.MousePosition.Y)
            ])
            result.append(KeyPress(Keys.WindowsMouseEvent, data))
        return result
Exemple #17
0
def test_feed_several(processor, handlers):
    with set_dummy_app():
        # First an unknown key first.
        processor.feed(KeyPress(Keys.ControlQ, ''))
        processor.process_keys()

        assert handlers.called == []

        # Followed by a know key sequence.
        processor.feed(KeyPress(Keys.ControlX, ''))
        processor.feed(KeyPress(Keys.ControlC, ''))
        processor.process_keys()

        assert handlers.called == ['controlx_controlc']

        # Followed by another unknown sequence.
        processor.feed(KeyPress(Keys.ControlR, ''))
        processor.feed(KeyPress(Keys.ControlS, ''))

        # Followed again by a know key sequence.
        processor.feed(KeyPress(Keys.ControlD, ''))
        processor.process_keys()

        assert handlers.called == ['controlx_controlc', 'control_d']
Exemple #18
0
 def _(event):
     " Map 'kj' to Escape. "
     event.cli.key_processor.feed(KeyPress(Keys.Escape))
Exemple #19
0
 def _(event):
     " Map 'eu' to Escape. "
     event.cli.key_processor.feed(KeyPress(Keys("escape")))
Exemple #20
0
 def _(event):
     """
     Typing 'kj' in Insert mode, should go back to navigation mode.
     """
     _logger.debug('Detected kj keys.')
     event.cli.key_processor.feed(KeyPress(Keys.Escape))
Exemple #21
0
 def _scroll_down(event: E) -> None:
     """
     Scroll down event without cursor position.
     """
     event.key_processor.feed(KeyPress(Keys.Down), first=True)
Exemple #22
0
 def _(event):
     " Map 'jj' to Escape. "
     event.cli.input_processor.feed(KeyPress(Keys.Escape))
Exemple #23
0
 def _(event):
     event.cli.key_processor.feed(KeyPress(Keys.Escape))
Exemple #24
0
 def _(event):
     event.cli.key_processor.feed_multiple([KeyPress("g"), KeyPress("_")])
    def _event_to_key_presses(self, ev: KEY_EVENT_RECORD) -> List[KeyPress]:
        """
        For this `KEY_EVENT_RECORD`, return a list of `KeyPress` instances.
        """
        assert type(ev) == KEY_EVENT_RECORD and ev.KeyDown

        result: Optional[KeyPress] = None

        control_key_state = ev.ControlKeyState
        u_char = ev.uChar.UnicodeChar
        # Use surrogatepass because u_char may be an unmatched surrogate
        ascii_char = u_char.encode("utf-8", "surrogatepass")

        # NOTE: We don't use `ev.uChar.AsciiChar`. That appears to be the
        # unicode code point truncated to 1 byte. See also:
        # https://github.com/ipython/ipython/issues/10004
        # https://github.com/jonathanslenders/python-prompt-toolkit/issues/389

        if u_char == "\x00":
            if ev.VirtualKeyCode in self.keycodes:
                result = KeyPress(self.keycodes[ev.VirtualKeyCode], "")
        else:
            if ascii_char in self.mappings:
                if self.mappings[ascii_char] == Keys.ControlJ:
                    u_char = (
                        "\n"  # Windows sends \n, turn into \r for unix compatibility.
                    )
                result = KeyPress(self.mappings[ascii_char], u_char)
            else:
                result = KeyPress(u_char, u_char)

        # First we handle Shift-Control-Arrow/Home/End (need to do this first)
        if ((control_key_state & self.LEFT_CTRL_PRESSED
             or control_key_state & self.RIGHT_CTRL_PRESSED)
                and control_key_state & self.SHIFT_PRESSED and result):
            mapping: Dict[str, str] = {
                Keys.Left: Keys.ControlShiftLeft,
                Keys.Right: Keys.ControlShiftRight,
                Keys.Up: Keys.ControlShiftUp,
                Keys.Down: Keys.ControlShiftDown,
                Keys.Home: Keys.ControlShiftHome,
                Keys.End: Keys.ControlShiftEnd,
                Keys.Insert: Keys.ControlShiftInsert,
                Keys.PageUp: Keys.ControlShiftPageUp,
                Keys.PageDown: Keys.ControlShiftPageDown,
            }
            result.key = mapping.get(result.key, result.key)

        # Correctly handle Control-Arrow/Home/End and Control-Insert/Delete keys.
        if (control_key_state & self.LEFT_CTRL_PRESSED
                or control_key_state & self.RIGHT_CTRL_PRESSED) and result:
            mapping = {
                Keys.Left: Keys.ControlLeft,
                Keys.Right: Keys.ControlRight,
                Keys.Up: Keys.ControlUp,
                Keys.Down: Keys.ControlDown,
                Keys.Home: Keys.ControlHome,
                Keys.End: Keys.ControlEnd,
                Keys.Insert: Keys.ControlInsert,
                Keys.Delete: Keys.ControlDelete,
                Keys.PageUp: Keys.ControlPageUp,
                Keys.PageDown: Keys.ControlPageDown,
            }
            result.key = mapping.get(result.key, result.key)

        # Turn 'Tab' into 'BackTab' when shift was pressed.
        # Also handle other shift-key combination
        if control_key_state & self.SHIFT_PRESSED and result:
            mapping = {
                Keys.Tab: Keys.BackTab,
                Keys.Left: Keys.ShiftLeft,
                Keys.Right: Keys.ShiftRight,
                Keys.Up: Keys.ShiftUp,
                Keys.Down: Keys.ShiftDown,
                Keys.Home: Keys.ShiftHome,
                Keys.End: Keys.ShiftEnd,
                Keys.Insert: Keys.ShiftInsert,
                Keys.Delete: Keys.ShiftDelete,
                Keys.PageUp: Keys.ShiftPageUp,
                Keys.PageDown: Keys.ShiftPageDown,
            }
            result.key = mapping.get(result.key, result.key)

        # Turn 'Space' into 'ControlSpace' when control was pressed.
        if ((control_key_state & self.LEFT_CTRL_PRESSED
             or control_key_state & self.RIGHT_CTRL_PRESSED) and result
                and result.data == " "):
            result = KeyPress(Keys.ControlSpace, " ")

        # Turn Control-Enter into META-Enter. (On a vt100 terminal, we cannot
        # detect this combination. But it's really practical on Windows.)
        if ((control_key_state & self.LEFT_CTRL_PRESSED
             or control_key_state & self.RIGHT_CTRL_PRESSED) and result
                and result.key == Keys.ControlJ):
            return [KeyPress(Keys.Escape, ""), result]

        # Return result. If alt was pressed, prefix the result with an
        # 'Escape' key, just like unix VT100 terminals do.

        # NOTE: Only replace the left alt with escape. The right alt key often
        #       acts as altgr and is used in many non US keyboard layouts for
        #       typing some special characters, like a backslash. We don't want
        #       all backslashes to be prefixed with escape. (Esc-\ has a
        #       meaning in E-macs, for instance.)
        if result:
            meta_pressed = control_key_state & self.LEFT_ALT_PRESSED

            if meta_pressed:
                return [KeyPress(Keys.Escape, ""), result]
            else:
                return [result]

        else:
            return []
Exemple #26
0
 def _(event):
     " Scroll down event without cursor position. "
     event.key_processor.feed(KeyPress(Keys.Down), first=True)
    def _event_to_key_presses(self, ev):
        """
        For this `KEY_EVENT_RECORD`, return a list of `KeyPress` instances.
        """
        assert type(ev) == KEY_EVENT_RECORD and ev.KeyDown

        result = None

        u_char = ev.uChar.UnicodeChar
        ascii_char = u_char.encode('utf-8')

        # NOTE: We don't use `ev.uChar.AsciiChar`. That appears to be latin-1
        #       encoded. See also:
        # https://github.com/ipython/ipython/issues/10004
        # https://github.com/jonathanslenders/python-prompt-toolkit/issues/389

        if u_char == '\x00':
            if ev.VirtualKeyCode in self.keycodes:
                result = KeyPress(self.keycodes[ev.VirtualKeyCode], '')
        else:
            if ascii_char in self.mappings:
                if self.mappings[ascii_char] == Keys.ControlJ:
                    u_char = '\n'  # Windows sends \n, turn into \r for unix compatibility.
                result = KeyPress(self.mappings[ascii_char], u_char)
            else:
                result = KeyPress(u_char, u_char)

        # Correctly handle Control-Arrow keys.
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED or
                ev.ControlKeyState & self.RIGHT_CTRL_PRESSED) and result:
            if result.key == Keys.Left:
                result.key = Keys.ControlLeft

            if result.key == Keys.Right:
                result.key = Keys.ControlRight

            if result.key == Keys.Up:
                result.key = Keys.ControlUp

            if result.key == Keys.Down:
                result.key = Keys.ControlDown

        # Turn 'Tab' into 'BackTab' when shift was pressed.
        if ev.ControlKeyState & self.SHIFT_PRESSED and result:
            if result.key == Keys.Tab:
                result.key = Keys.BackTab

        # Turn 'Space' into 'ControlSpace' when control was pressed.
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED or
                ev.ControlKeyState & self.RIGHT_CTRL_PRESSED) and result and result.data == ' ':
            result = KeyPress(Keys.ControlSpace, ' ')

        # Turn Control-Enter into META-Enter. (On a vt100 terminal, we cannot
        # detect this combination. But it's really practical on Windows.)
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED or
                ev.ControlKeyState & self.RIGHT_CTRL_PRESSED) and result and \
                result.key == Keys.ControlJ:
            return [KeyPress(Keys.Escape, ''), result]

        # Return result. If alt was pressed, prefix the result with an
        # 'Escape' key, just like unix VT100 terminals do.

        # NOTE: Only replace the left alt with escape. The right alt key often
        #       acts as altgr and is used in many non US keyboard layouts for
        #       typing some special characters, like a backslash. We don't want
        #       all backslashes to be prefixed with escape. (Esc-\ has a
        #       meaning in E-macs, for instance.)
        if result:
            meta_pressed = ev.ControlKeyState & self.LEFT_ALT_PRESSED

            if meta_pressed:
                return [KeyPress(Keys.Escape, ''), result]
            else:
                return [result]

        else:
            return []
Exemple #28
0
 def _(event):
     event.cli.key_processor.feed(KeyPress(Keys.Up))
Exemple #29
0
def vi_movement_mode(event):
    """Exit vi mode."""
    event.cli.key_processor.feed(KeyPress(Keys.Escape))
Exemple #30
0
    def _event_to_key_presses(self, ev):
        """
        For this `KEY_EVENT_RECORD`, return a list of `KeyPress` instances.
        """
        assert type(ev) == KEY_EVENT_RECORD and ev.KeyDown

        result = None

        u_char = ev.uChar.UnicodeChar
        ascii_char = u_char.encode('utf-8')

        # NOTE: We don't use `ev.uChar.AsciiChar`. That appears to be latin-1
        #       encoded. See also:
        # https://github.com/ipython/ipython/issues/10004
        # https://github.com/jonathanslenders/python-prompt-toolkit/issues/389

        if u_char == '\x00':
            if ev.VirtualKeyCode in self.keycodes:
                result = KeyPress(self.keycodes[ev.VirtualKeyCode], '')
        else:
            if ascii_char in self.mappings:
                if self.mappings[ascii_char] == Keys.ControlJ:
                    u_char = '\n'  # Windows sends \n, turn into \r for unix compatibility.
                result = KeyPress(self.mappings[ascii_char], u_char)
            else:
                result = KeyPress(u_char, u_char)

        # Correctly handle Control-Arrow keys.
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED
                or ev.ControlKeyState & self.RIGHT_CTRL_PRESSED) and result:
            if result.key == Keys.Left:
                result.key = Keys.ControlLeft

            if result.key == Keys.Right:
                result.key = Keys.ControlRight

            if result.key == Keys.Up:
                result.key = Keys.ControlUp

            if result.key == Keys.Down:
                result.key = Keys.ControlDown

        # Turn 'Tab' into 'BackTab' when shift was pressed.
        if ev.ControlKeyState & self.SHIFT_PRESSED and result:
            if result.key == Keys.Tab:
                result.key = Keys.BackTab

        # Turn 'Space' into 'ControlSpace' when control was pressed.
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED or ev.ControlKeyState
                & self.RIGHT_CTRL_PRESSED) and result and result.data == ' ':
            result = KeyPress(Keys.ControlSpace, ' ')

        # Turn Control-Enter into META-Enter. (On a vt100 terminal, we cannot
        # detect this combination. But it's really practical on Windows.)
        if (ev.ControlKeyState & self.LEFT_CTRL_PRESSED or
            ev.ControlKeyState & self.RIGHT_CTRL_PRESSED) and result and \
                result.key == Keys.ControlJ:
            return [KeyPress(Keys.Escape, ''), result]

        # Return result. If alt was pressed, prefix the result with an
        # 'Escape' key, just like unix VT100 terminals do.

        # NOTE: Only replace the left alt with escape. The right alt key often
        #       acts as altgr and is used in many non US keyboard layouts for
        #       typing some special characters, like a backslash. We don't want
        #       all backslashes to be prefixed with escape. (Esc-\ has a
        #       meaning in E-macs, for instance.)
        if result:
            meta_pressed = ev.ControlKeyState & self.LEFT_ALT_PRESSED

            if meta_pressed:
                return [KeyPress(Keys.Escape, ''), result]
            else:
                return [result]

        else:
            return []
Exemple #31
0
 def _(event):
     event.cli.key_processor.feed(KeyPress("0"))